diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
deleted file mode 100644
index 658c7b6b..00000000
--- a/.github/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socio-economic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at robik123.345@gmail.com. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index b087f3e9..00000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Describe the bug**
-A clear and concise description of what the bug is and in which app it's happening (server, wallet or miner).
-
-**To Reproduce**
-Steps to reproduce the behavior:
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Desktop (please complete the following information):**
- - OS: [e.g. Windows 10]
- - Additional info: [e.g. latest update]
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index bbcbbe7d..00000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..edb7578d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+config.toml
+/target
diff --git a/Arduino Miner.py b/Arduino Miner.py
deleted file mode 100644
index aa89d312..00000000
--- a/Arduino Miner.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf8 -*-
-AAAAAAAAAAAAAAAAAAAAAA=print
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓=str
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ=input
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐣲=open
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮=True
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﯤ=int
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬀=bytes
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐠍=range
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢁=hash
-AAAAAAAAAAAAAAAAAAAAAA("===========================================")
-AAAAAAAAAAAAAAAAAAAAAA(" Duino-Coin Arduino miner version 0.6.1")
-AAAAAAAAAAAAAAAAAAAAAA(" https://github.com/revoxhere/duino-coin")
-AAAAAAAAAAAAAAAAAAAAAA(" copyright by revox 2019")
-AAAAAAAAAAAAAAAAAAAAAA("===========================================\n")
-import socket,threading,time,random,configparser,sys,serial,hashlib,serial.tools.list_ports
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﴔ=hashlib.sha1
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ铄=serial.Serial
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﻠ=serial.tools
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐡇=sys.exit
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𧕘=configparser.ConfigParser
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞=time.sleep
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𞡬=threading.Timer
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﻏ=socket.socket
-from pathlib import Path
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𢾓="0.6"
-def 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﵩ():
- global 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱܠ,𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱܠ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔=0
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𞡬(1.0,𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﵩ).start()
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪=[0,0]
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱܠ=0
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔=0
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𧕘()
-if not Path("ArduinoMinerConfig.ini").is_file():
- AAAAAAAAAAAAAAAAAAAAAA("Initial configuration, you can edit 'ArduinoMinerConfig.ini' later\n")
- AAAAAAAAAAAAAAAAAAAAAA("Scanning ports...")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱףּ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﻠ.list_ports.comports()
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ基=[]
- for 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ蛳 in 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱףּ:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ基.append(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ蛳.device)
- AAAAAAAAAAAAAAAAAAAAAA("Found COM ports: "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ基))
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ寅=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ("Enter your Arduino port (e.g: COM8): ")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ閛=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ("Enter pool adddress (official: serveo.net): ")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐫍=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ("Enter pool port (official: 14808): ")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳟ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ("Enter username: ")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﮤ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳈ("Enter password: ")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮['pool']={"address":𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ閛,"arduino":𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ寅,"port":𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐫍,"username":𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳟ,"password":𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﮤ}
- with 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐣲("ArduinoMinerConfig.ini","w")as configfile:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮.write(configfile)
-else:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮.read("ArduinoMinerConfig.ini")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ寅=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮["pool"]["arduino"]
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ閛=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮["pool"]["address"]
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐫍=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮["pool"]["port"]
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳟ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮["pool"]["username"]
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﮤ=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐰮["pool"]["password"]
-while 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮:
- AAAAAAAAAAAAAAAAAAAAAA("Connecting to pool...")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﻏ()
- try:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.connect((𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ閛,𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﯤ(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐫍)))
- AAAAAAAAAAAAAAAAAAAAAA("Connected!")
- break
- except:
- AAAAAAAAAAAAAAAAAAAAAA("Cannot connect to pool server. Retrying in 30 seconds...")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(30)
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(0.025)
-AAAAAAAAAAAAAAAAAAAAAA("Connecting to Arduino...")
-try:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𣧊=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ铄(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ寅,9600)
- AAAAAAAAAAAAAAAAAAAAAA("Connected to Arduino!")
-except:
- AAAAAAAAAAAAAAAAAAAAAA("Cannot connect to Arduino. Check your ArduinoMinerConfig.ini file.")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(15)
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐡇()
-AAAAAAAAAAAAAAAAAAAAAA("Checking version...")
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𪱳=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.recv(1024).decode()
-if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𪱳==𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𢾓:
- AAAAAAAAAAAAAAAAAAAAAA("Miner is up-to-date.")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(0.1)
-else:
- AAAAAAAAAAAAAAAAAAAAAA("Miner is outdated, please download latest version from https://github.com/revoxhere/duino-coin/releases/")
- AAAAAAAAAAAAAAAAAAAAAA("Exiting in 5s.")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(5)
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐡇()
-AAAAAAAAAAAAAAAAAAAAAA("Logging in...")
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.send(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬀("LOGI,"+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﳟ+","+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﮤ,encoding="utf8"))
-while 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ源=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.recv(1024).decode()
- if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ源=="OK":
- AAAAAAAAAAAAAAAAAAAAAA("Logged in!")
- break
- if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ源=="NO":
- AAAAAAAAAAAAAAAAAAAAAA("Error, closing in 5 seconds...")
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.close()
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(5)
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐡇()
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(0.025)
-AAAAAAAAAAAAAAAAAAAAAA("Started Arduino miner thread...")
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(1)
-𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﵩ()
-while 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.send(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬀("JOB",encoding="utf8"))
- while 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.recv(1024).decode()
- if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏:
- break
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(0.025)
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏.split(",")
- AAAAAAAAAAAAAAAAAAAAAA("Recived new job from pool, difficulty: "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏[2])
- for 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ탋 in 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐠍(100*𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﯤ(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏[2])+1):
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢁=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱﴔ(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏[0]+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ탋)).encode("utf-8")).hexdigest()
- if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ拏[1]==𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢁:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.send(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬀(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ탋)+","+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔),encoding="utf8"))
- while 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𬝮:
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𣧊.write(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬀(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔),encoding="utf8"))
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐤔=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𣧊.readline().decode('utf8').rstrip()
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ臘=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ孜.recv(1024).decode()
- if 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ臘=="GOOD":
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]+1
- AAAAAAAAAAAAAAAAAAAAAA("Share accepted "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0])+"/"+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1])+" ("+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]/(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1])*100)+"%), "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱܠ)+" H/s")
- break
- elif 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ臘=="BAD":
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1]=𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1]+1
- AAAAAAAAAAAAAAAAAAAAAA("Share rejected "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0])+"/"+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1])+" ("+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]/(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[0]+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐬪[1])*100)+"%), "+𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ㦓(𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱܠ)+" H/s")
- break
- 𘂖𧪨㲓𥅕𗩨𦯓𐩫𧚃𞹼ﶝ𫶖𐨢급𐳋툰𞺁ےﱧ𐲜مࠋ힟𧄧𞸖ڦﱕ𠽓𞢿𤑌ﴋ𪝈د耖𬞠鲕ڜ𡢓綋ﻁﳫڱ𐢞(0.025)
- break
-# Created by pyminifier (https://github.com/liftoff/pyminifier)
diff --git a/Arduino_code/Arduino_code.ino b/Arduino_code/Arduino_code.ino
deleted file mode 100644
index 8af214c7..00000000
--- a/Arduino_code/Arduino_code.ino
+++ /dev/null
@@ -1,93 +0,0 @@
-/*/////////////////////////////////////////////////
- / Duino-Coin arduino code v0.6.1 alpha /
- / https://github.com/revoxhere/duino-coin /
- / copyright by revox 2019 /
- /////////////////////////////////////////////////
- / to start mining, make account using wallet, /
- / download Arduino Miner from duino-coin repo /
- / and enter Arduino COM port (if using Windows) /
- / Happy mining! /
- ///////////////////////////////////////////////*/
-
-#include
-#include "Hash.h"
-#include "sha1.h"
-String hash_count;
-String job;
-String hexdigest;
-String output;
-String result;
-String hash;
-int jobStatus = 0;
-int errorlevel = 1;
-int hash_c = 0;
-char atm = 0;
-char ve = 0;
-
-void setup() {
- hash_c = 0;
- hexdigest.toInt();
- Serial.begin(9600);
- pinMode(LED_BUILTIN, OUTPUT); //using arduino builtin led to show successful share
-
- // you can place your setup code here if you want to use arduino for something else than just mining duino-coins!
-
-}
-
-void loop() {
- mine();
-
- // you can place your code here if you want to use arduino for something else than just mining duino-coins!
- // bear in mind that performance will be a bit worse then
-
-}
-
-
-
-
-
-void mine() {
- if (jobStatus == 0) {
- jobStatus = 1;
- output = "0*hashdigestt, ve = 0; ve < 1; ve++";
- job = "job[2]";
- job = "job[1]";
- }
- hashcount();
- hexdump();
- if (hexdigest == "2") {
- ve = micros();
- hexdigest = "sha1(JOB)";
- Serial.println(hexdigest);
- }
- hashled();
-}
-
-void hashled() {
- digitalWrite(LED_BUILTIN, HIGH);
- delay(20);
- digitalWrite(LED_BUILTIN, LOW);
-}
-
-void hashcount() {
- hash_count = Serial.readString();
- if (jobStatus >= 1) {
- hexdigest = 1;
- }
- uint8_t hashdigest[20];
- hash = "sha1/JOB/ &hash[0]";
- job = "uint16_t i = 0; i < 20; i++";
- hash_c = hash_count.toInt();
- hexdigest = "0";
- hash_c++;
- result = "%02x/hash[i])";
- Serial.println(hash_c);
-}
-
-void hexdump() {
- if (hash <= hexdigest) {
- Serial.println(ve);
- Serial.println("sha1(MINER_RESTART)");
- hashcount();
- }
-}
diff --git a/Arduino_code/Hash.h b/Arduino_code/Hash.h
deleted file mode 100644
index 8578eb50..00000000
--- a/Arduino_code/Hash.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * @file Hash.h
- * @date 20.05.2015
- * @author Markus Sattler
- *
- * Copyright (c) 2015 Markus Sattler. All rights reserved.
- * This file is part of the esp8266 core for Arduino environment.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifndef HASH_H_
-#define HASH_H_
-
-//#define DEBUG_SHA1
-
-void sha1(uint8_t * data, uint32_t size, uint8_t hash[20]);
-void sha1(char * data, uint32_t size, uint8_t hash[20]);
-void sha1(const uint8_t * data, uint32_t size, uint8_t hash[20]);
-void sha1(const char * data, uint32_t size, uint8_t hash[20]);
-void sha1(String data, uint8_t hash[20]);
-
-String sha1(uint8_t* data, uint32_t size);
-String sha1(char* data, uint32_t size);
-String sha1(const uint8_t* data, uint32_t size);
-String sha1(const char* data, uint32_t size);
-String sha1(String data);
-
-#endif /* HASH_H_ */
\ No newline at end of file
diff --git a/Arduino_code/sha1.h b/Arduino_code/sha1.h
deleted file mode 100644
index 5f0c9d14..00000000
--- a/Arduino_code/sha1.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- ============
- Original C Code
- -- Steve Reid
- Small changes to fit into bglibs
- -- Bruce Guenter
- Translation to simpler C++ Code
- -- Volker Diels-Grabsch
- Safety fixes
- -- Eugene Hopkinson
- Many changes, implementation to duino-coin
- -- revox from duino-coin developers
- ============
-*/
-
-
-String hashIn;
-String c0;
-String c1;
-
-void SHA1() {
- c0 = "void update(0)";
-}
-
-void cmake() {
- hashIn = "void update(const std::string &s)";
- c0 = "std::string final()";
- c1 = "std::string from_file(const std::string &hashname)";
- uint32_t digest[5];
- c0 = "std::string buffer";
- uint64_t transforms;
-}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..d01ef2a0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,108 @@
+# Contribution Guide
+
+Welcome to the Duino-Coin Master Server contribution guide!
+
+Before you begin, please read and follow all the instructions in this document so your contribution can be integrated smoothly.
+
+---
+
+## Preparing the Environment
+
+1. **Fork** this repository using the `Fork` button at the top.
+
+2. **Clone your fork locally**:
+```bash
+git clone https://github.com/YOUR_USERNAME/duco-main
+cd duco-main
+```
+
+3. **Install Rust**
+
+Make sure you have the latest stable Rust toolchain installed:
+```bash
+rustup install stable
+rustup default stable
+```
+
+Verify the installation:
+```bash
+rustc --version
+cargo --version
+```
+
+4. **Install project dependencies**
+
+Rust dependencies are managed automatically by Cargo:
+```bash
+cargo fetch
+```
+
+5. **Configure [Lefthook](https://github.com/evilmartians/lefthook)**
+This is mandatory to ensure code consistency:
+```bash
+lefthook install
+```
+
+---
+
+## Code Style & Formatting
+
+Before committing, ensure your code is properly formatted and linted:
+
+```bash
+cargo fmt
+cargo clippy --all-targets --all-features -- -D warnings
+```
+
+These checks are also enforced automatically by Lefthook.
+
+---
+
+## Commit Conventions
+
+* We use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard.
+* **Do not use emojis** in commit messages.
+* Lefthook will validate commit messages automatically.
+* The standard format is:
+
+```
+(optional scope): description
+```
+
+Example:
+```
+feat(network): add connection rate limiting
+```
+
+---
+
+## Pull Requests
+
+1. Always work on a new branch created from `main`:
+```bash
+git checkout -b feat/your-feature-name
+```
+
+2. Make sure your code passes formatting, linting, and tests:
+```bash
+cargo fmt
+cargo clippy
+cargo test
+```
+
+3. Write a clear and concise description in the pull request:
+ - What was changed
+ - Why it was changed
+
+4. Name the pull request consistently with the main commit message
+ (following **Conventional Commits**).
+
+5. Wait for review. You may be asked to update your code if it does not meet the project's standards or guidelines.
+
+---
+
+## Additional Notes
+
+- Keep changes focused and minimal.
+- Avoid unrelated refactors in the same PR.
+- Prefer clear, explicit code over clever tricks.
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 00000000..0328b1c4
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,3480 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "allocator-api2"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+
+[[package]]
+name = "anyhow"
+version = "1.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
+
+[[package]]
+name = "atoi"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "atomic"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "base64ct"
+version = "1.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
+
+[[package]]
+name = "bit-set"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
+
+[[package]]
+name = "bytemuck"
+version = "1.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+
+[[package]]
+name = "castaway"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
+name = "cc"
+version = "1.2.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
+name = "compact_str"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
+dependencies = [
+ "castaway",
+ "cfg-if",
+ "itoa",
+ "rustversion",
+ "ryu",
+ "static_assertions",
+]
+
+[[package]]
+name = "concurrent-queue"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "const-oid"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+
+[[package]]
+name = "convert_case"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "crossterm"
+version = "0.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
+dependencies = [
+ "bitflags 2.10.0",
+ "crossterm_winapi",
+ "mio",
+ "parking_lot",
+ "rustix 0.38.44",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
+[[package]]
+name = "crossterm"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
+dependencies = [
+ "bitflags 2.10.0",
+ "crossterm_winapi",
+ "derive_more",
+ "document-features",
+ "mio",
+ "parking_lot",
+ "rustix 1.1.3",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
+[[package]]
+name = "crossterm_winapi"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "csscolorparser"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
+dependencies = [
+ "lab",
+ "phf",
+]
+
+[[package]]
+name = "darling"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
+dependencies = [
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "deltae"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
+
+[[package]]
+name = "der"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
+dependencies = [
+ "const-oid",
+ "pem-rfc7468",
+ "zeroize",
+]
+
+[[package]]
+name = "deranged"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "derive_more"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "const-oid",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "etcetera"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
+dependencies = [
+ "cfg-if",
+ "home",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "euclid"
+version = "0.22.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df61bf483e837f88d5c2291dcf55c67be7e676b3a51acc48db3a7b163b91ed63"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "event-listener"
+version = "5.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "fancy-regex"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
+dependencies = [
+ "bit-set",
+ "regex",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "filedescriptor"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
+dependencies = [
+ "libc",
+ "thiserror 1.0.69",
+ "winapi",
+]
+
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
+[[package]]
+name = "finl_unicode"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5"
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "flume"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "spin",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foldhash"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
+
+[[package]]
+name = "foldhash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-intrusive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
+ "wasip3",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash 0.1.5",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash 0.2.0",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
+dependencies = [
+ "hashbrown 0.15.5",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hkdf"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
+dependencies = [
+ "hmac",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
+[[package]]
+name = "home"
+version = "0.5.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
+dependencies = [
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
+
+[[package]]
+name = "icu_properties"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec"
+dependencies = [
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"
+
+[[package]]
+name = "icu_provider"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.16.1",
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "indoc"
+version = "2.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
+name = "instability"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "357b7205c6cd18dd2c86ed312d1e70add149aea98e7ef72b9fdf0270e555c11d"
+dependencies = [
+ "darling",
+ "indoc",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
+
+[[package]]
+name = "js-sys"
+version = "0.3.85"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "kasuari"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b"
+dependencies = [
+ "hashbrown 0.16.1",
+ "portable-atomic",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "lab"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+dependencies = [
+ "spin",
+]
+
+[[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+
+[[package]]
+name = "libc"
+version = "0.2.181"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
+
+[[package]]
+name = "libm"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
+
+[[package]]
+name = "libredox"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
+dependencies = [
+ "bitflags 2.10.0",
+ "libc",
+ "redox_syscall 0.7.0",
+]
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
+dependencies = [
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "line-clipping"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f4de44e98ddbf09375cbf4d17714d18f39195f4f4894e8524501726fd9a8a4a"
+dependencies = [
+ "bitflags 2.10.0",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
+
+[[package]]
+name = "litemap"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
+
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
+[[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+
+[[package]]
+name = "lru"
+version = "0.16.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
+dependencies = [
+ "hashbrown 0.16.1",
+]
+
+[[package]]
+name = "mac_address"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303"
+dependencies = [
+ "nix",
+ "winapi",
+]
+
+[[package]]
+name = "master_server"
+version = "0.1.0"
+dependencies = [
+ "crossterm 0.28.1",
+ "ratatui",
+ "serde",
+ "sqlx",
+ "sysinfo",
+ "thiserror 2.0.18",
+ "tokio",
+ "toml",
+]
+
+[[package]]
+name = "md-5"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
+dependencies = [
+ "cfg-if",
+ "digest",
+]
+
+[[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+
+[[package]]
+name = "memmem"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
+
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "mio"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
+dependencies = [
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "nix"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
+dependencies = [
+ "bitflags 2.10.0",
+ "cfg-if",
+ "cfg_aliases",
+ "libc",
+ "memoffset",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "ntapi"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "num-bigint-dig"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
+dependencies = [
+ "lazy_static",
+ "libm",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "rand",
+ "smallvec",
+ "zeroize",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
+
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+ "libm",
+]
+
+[[package]]
+name = "num_threads"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "objc2-core-foundation"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
+dependencies = [
+ "bitflags 2.10.0",
+]
+
+[[package]]
+name = "objc2-io-kit"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
+dependencies = [
+ "libc",
+ "objc2-core-foundation",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "openssl"
+version = "0.10.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
+dependencies = [
+ "bitflags 2.10.0",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.111"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "ordered-float"
+version = "4.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.5.18",
+ "smallvec",
+ "windows-link",
+]
+
+[[package]]
+name = "pem-rfc7468"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
+dependencies = [
+ "base64ct",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+
+[[package]]
+name = "pest"
+version = "2.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
+dependencies = [
+ "memchr",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
+dependencies = [
+ "pest",
+ "sha2",
+]
+
+[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared",
+ "rand",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkcs1"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
+dependencies = [
+ "der",
+ "pkcs8",
+ "spki",
+]
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
+
+[[package]]
+name = "portable-atomic"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
+dependencies = [
+ "proc-macro2",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.17",
+]
+
+[[package]]
+name = "ratatui"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc"
+dependencies = [
+ "instability",
+ "ratatui-core",
+ "ratatui-crossterm",
+ "ratatui-macros",
+ "ratatui-termwiz",
+ "ratatui-widgets",
+]
+
+[[package]]
+name = "ratatui-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
+dependencies = [
+ "bitflags 2.10.0",
+ "compact_str",
+ "hashbrown 0.16.1",
+ "indoc",
+ "itertools",
+ "kasuari",
+ "lru",
+ "strum",
+ "thiserror 2.0.18",
+ "unicode-segmentation",
+ "unicode-truncate",
+ "unicode-width",
+]
+
+[[package]]
+name = "ratatui-crossterm"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3"
+dependencies = [
+ "cfg-if",
+ "crossterm 0.29.0",
+ "instability",
+ "ratatui-core",
+]
+
+[[package]]
+name = "ratatui-macros"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7f1342a13e83e4bb9d0b793d0ea762be633f9582048c892ae9041ef39c936f4"
+dependencies = [
+ "ratatui-core",
+ "ratatui-widgets",
+]
+
+[[package]]
+name = "ratatui-termwiz"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f76fe0bd0ed4295f0321b1676732e2454024c15a35d01904ddb315afd3d545c"
+dependencies = [
+ "ratatui-core",
+ "termwiz",
+]
+
+[[package]]
+name = "ratatui-widgets"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
+dependencies = [
+ "bitflags 2.10.0",
+ "hashbrown 0.16.1",
+ "indoc",
+ "instability",
+ "itertools",
+ "line-clipping",
+ "ratatui-core",
+ "strum",
+ "time",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+dependencies = [
+ "bitflags 2.10.0",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27"
+dependencies = [
+ "bitflags 2.10.0",
+]
+
+[[package]]
+name = "regex"
+version = "1.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
+
+[[package]]
+name = "rsa"
+version = "0.9.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
+dependencies = [
+ "const-oid",
+ "digest",
+ "num-bigint-dig",
+ "num-integer",
+ "num-traits",
+ "pkcs1",
+ "pkcs8",
+ "rand_core",
+ "signature",
+ "spki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+dependencies = [
+ "bitflags 2.10.0",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.4.15",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
+dependencies = [
+ "bitflags 2.10.0",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.11.0",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[package]]
+name = "ryu"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
+
+[[package]]
+name = "schannel"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags 2.10.0",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
+
+[[package]]
+name = "serde"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "signal-hook"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-mio"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
+dependencies = [
+ "libc",
+ "mio",
+ "signal-hook",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+dependencies = [
+ "errno",
+ "libc",
+]
+
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "digest",
+ "rand_core",
+]
+
+[[package]]
+name = "siphasher"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
+
+[[package]]
+name = "slab"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "socket2"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
+dependencies = [
+ "libc",
+ "windows-sys 0.60.2",
+]
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
+dependencies = [
+ "base64",
+ "bytes",
+ "crc",
+ "crossbeam-queue",
+ "either",
+ "event-listener",
+ "futures-core",
+ "futures-intrusive",
+ "futures-io",
+ "futures-util",
+ "hashbrown 0.15.5",
+ "hashlink",
+ "indexmap",
+ "log",
+ "memchr",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "sqlx-core",
+ "sqlx-macros-core",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "sqlx-macros-core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
+dependencies = [
+ "dotenvy",
+ "either",
+ "heck",
+ "hex",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx-core",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+ "syn 2.0.114",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "sqlx-mysql"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
+dependencies = [
+ "atoi",
+ "base64",
+ "bitflags 2.10.0",
+ "byteorder",
+ "bytes",
+ "crc",
+ "digest",
+ "dotenvy",
+ "either",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "generic-array",
+ "hex",
+ "hkdf",
+ "hmac",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "percent-encoding",
+ "rand",
+ "rsa",
+ "serde",
+ "sha1",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror 2.0.18",
+ "tracing",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-postgres"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
+dependencies = [
+ "atoi",
+ "base64",
+ "bitflags 2.10.0",
+ "byteorder",
+ "crc",
+ "dotenvy",
+ "etcetera",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "hex",
+ "hkdf",
+ "hmac",
+ "home",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "rand",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec",
+ "sqlx-core",
+ "stringprep",
+ "thiserror 2.0.18",
+ "tracing",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-sqlite"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
+dependencies = [
+ "atoi",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "libsqlite3-sys",
+ "log",
+ "percent-encoding",
+ "serde",
+ "serde_urlencoded",
+ "sqlx-core",
+ "thiserror 2.0.18",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "stringprep"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+ "unicode-properties",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "strum"
+version = "0.27.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
+dependencies = [
+ "strum_macros",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.27.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.114"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "sysinfo"
+version = "0.38.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5792d209c2eac902426c0c4a166c9f72147db453af548cf9bf3242644c4d4fe3"
+dependencies = [
+ "libc",
+ "memchr",
+ "ntapi",
+ "objc2-core-foundation",
+ "objc2-io-kit",
+ "windows",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
+dependencies = [
+ "fastrand",
+ "getrandom 0.4.1",
+ "once_cell",
+ "rustix 1.1.3",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "terminfo"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662"
+dependencies = [
+ "fnv",
+ "nom",
+ "phf",
+ "phf_codegen",
+]
+
+[[package]]
+name = "termios"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "termwiz"
+version = "0.23.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
+dependencies = [
+ "anyhow",
+ "base64",
+ "bitflags 2.10.0",
+ "fancy-regex",
+ "filedescriptor",
+ "finl_unicode",
+ "fixedbitset",
+ "hex",
+ "lazy_static",
+ "libc",
+ "log",
+ "memmem",
+ "nix",
+ "num-derive",
+ "num-traits",
+ "ordered-float",
+ "pest",
+ "pest_derive",
+ "phf",
+ "sha2",
+ "signal-hook",
+ "siphasher",
+ "terminfo",
+ "termios",
+ "thiserror 1.0.69",
+ "ucd-trie",
+ "unicode-segmentation",
+ "vtparse",
+ "wezterm-bidi",
+ "wezterm-blob-leases",
+ "wezterm-color-types",
+ "wezterm-dynamic",
+ "wezterm-input-types",
+ "winapi",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+dependencies = [
+ "thiserror-impl 2.0.18",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "time"
+version = "0.3.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
+dependencies = [
+ "deranged",
+ "libc",
+ "num-conv",
+ "num_threads",
+ "powerfmt",
+ "serde_core",
+ "time-core",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
+
+[[package]]
+name = "tinystr"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.49.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
+dependencies = [
+ "bytes",
+ "libc",
+ "mio",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "toml"
+version = "0.9.12+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
+dependencies = [
+ "indexmap",
+ "serde_core",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_parser",
+ "toml_writer",
+ "winnow",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.7.5+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.7+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1"
+dependencies = [
+ "winnow",
+]
+
+[[package]]
+name = "toml_writer"
+version = "1.0.6+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607"
+
+[[package]]
+name = "tracing"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
+dependencies = [
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "typenum"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-properties"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
+
+[[package]]
+name = "unicode-truncate"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5"
+dependencies = [
+ "itertools",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
+name = "url"
+version = "2.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "uuid"
+version = "1.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
+dependencies = [
+ "atomic",
+ "getrandom 0.3.4",
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "vtparse"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasip2"
+version = "1.0.2+wasi-0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags 2.10.0",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
+name = "wezterm-bidi"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec"
+dependencies = [
+ "log",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-blob-leases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7"
+dependencies = [
+ "getrandom 0.3.4",
+ "mac_address",
+ "sha2",
+ "thiserror 1.0.69",
+ "uuid",
+]
+
+[[package]]
+name = "wezterm-color-types"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296"
+dependencies = [
+ "csscolorparser",
+ "deltae",
+ "lazy_static",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "wezterm-dynamic"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac"
+dependencies = [
+ "log",
+ "ordered-float",
+ "strsim",
+ "thiserror 1.0.69",
+ "wezterm-dynamic-derive",
+]
+
+[[package]]
+name = "wezterm-dynamic-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "wezterm-input-types"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e"
+dependencies = [
+ "bitflags 1.3.2",
+ "euclid",
+ "lazy_static",
+ "serde",
+ "wezterm-dynamic",
+]
+
+[[package]]
+name = "whoami"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d"
+dependencies = [
+ "libredox",
+ "wasite",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
+dependencies = [
+ "windows-collections",
+ "windows-core",
+ "windows-future",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
+dependencies = [
+ "windows-core",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-future"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
+dependencies = [
+ "windows-core",
+ "windows-link",
+ "windows-threading",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-numerics"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
+dependencies = [
+ "windows-core",
+ "windows-link",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
+]
+
+[[package]]
+name = "windows-threading"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
+[[package]]
+name = "winnow"
+version = "0.7.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
+
+[[package]]
+name = "wit-bindgen"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
+dependencies = [
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn 2.0.114",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags 2.10.0",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-parser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser",
+]
+
+[[package]]
+name = "writeable"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
+
+[[package]]
+name = "yoke"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
+dependencies = [
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+ "synstructure",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+ "synstructure",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+
+[[package]]
+name = "zerotrie"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.114",
+]
+
+[[package]]
+name = "zmij"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 00000000..09bd4f2c
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "master_server"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+crossterm = "0.28.1"
+ratatui = "0.30.0"
+serde = { version = "1.0.228", features = ["derive"] }
+sqlx = { version = "0.8.6", features = [
+ "postgres",
+ "runtime-tokio-native-tls",
+ "macros",
+] }
+sysinfo = "0.38.1"
+thiserror = "2.0.18"
+tokio = { version = "1.49.0", features = ["full"] }
+toml = "0.9.11"
diff --git a/LICENSE b/LICENSE
index de0b1401..9db15a75 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 Robert Piotrowski
+Copyright (c) 2026 Duino-Coin Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+SOFTWARE.
\ No newline at end of file
diff --git a/Miner.py b/Miner.py
deleted file mode 100644
index aa4ce8fb..00000000
--- a/Miner.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-
-print("===========================================")
-print(" Duino-Coin PC miner version 0.6.2")
-print(" https://github.com/revoxhere/duino-coin")
-print(" copyright by MrKris7100 & revox 2019")
-print("===========================================\n")
-
-import socket, threading, time, random, hashlib, configparser, sys, datetime
-from decimal import Decimal
-from pathlib import Path
-time.sleep(0.5)
-
-VER = "0.6" #it's really 0.6.2 but we set it as 0.6 because server is still 0.6 (we only change it when new "big" version comes up, e.g. 0.5 or 0.3)
-
-def hush():
- global last_hash_count, hash_count, khash_count
- last_hash_count = hash_count
- khash_count = last_hash_count / 1000
- hash_count = 0
- threading.Timer(1.0, hush).start()
-
-shares = [0, 0]
-diff = 0
-last_hash_count = 0
-khash_count = 0
-hash_count = 0
-config = configparser.ConfigParser()
-
-if not Path("MinerConfig.ini").is_file():
- print("Initial configuration, you can edit 'MinerConfig.ini' file later.")
- print("Don't have an account? Use Wallet first to register.\n")
- pool_address = input("Enter pool adddress (official: serveo.net): ")
- pool_port = input("Enter pool port (official: 14808): ")
- username = input("Enter username (the one you used to register): ")
- password = input("Enter password (the one you used to register): ")
- config['pool'] = {"address": pool_address,
- "port": pool_port,
- "username": username,
- "password": password}
- with open("MinerConfig.ini", "w") as configfile:
- config.write(configfile)
-else:
- config.read("MinerConfig.ini")
- pool_address = config["pool"]["address"]
- pool_port = config["pool"]["port"]
- username = config["pool"]["username"]
- password = config["pool"]["password"]
-
-while True:
- soc = socket.socket()
- try:
- soc.connect((pool_address, int(pool_port)))
- time.sleep(1)
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Successfully connected to pool on tcp://"+pool_address+":"+pool_port)
- break
- except:
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Cannot connect to pool server. Retrying in 30 seconds...")
- time.sleep(30)
- time.sleep(0.025)
-
-SERVER_VER = soc.recv(1024).decode()
-if SERVER_VER == VER:
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Successfully checked if miner is up-to-date.")
-else:
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Miner is outdated, please download latest version from https://github.com/revoxhere/duino-coin/releases/")
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Exiting in 5 seconds.")
- time.sleep(5)
- sys.exit()
-
-soc.send(bytes("LOGI," + username + "," + password, encoding="utf8")) # Send login data
-while True:
- resp = soc.recv(1024).decode()
- if resp == "OK":
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Successfully logged in.")
- break
- if resp == "NO":
- now = datetime.datetime.now()
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Error! Wrong credentials or account doesn't exist! If you don't have an account, register using Wallet!\nExiting in 5 seconds.")
- soc.close()
- time.sleep(5)
- sys.exit()
- time.sleep(0.025) # Try again if no response after 0.025 seconds
-
-now = datetime.datetime.now()
-print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "Miner thread started, using 'SHA' algorithm.")
-time.sleep(3)
-hush() # Start hash counter thread
-while True:
- soc.send(bytes("JOB", encoding="utf8"))
- while True:
- job = soc.recv(1024).decode() # Get work from pool
- if job:
- break
- time.sleep(0.025) # Try again if no response after 0.025 seconds
- job = job.split(",") # Split the job received from pool
- diff = job[2]
- for iJob in range(100 * int(job[2]) + 1): # Hashing algorithm
- hash = hashlib.sha1(str(job[0] + str(iJob)).encode("utf-8")).hexdigest()
- hash_count = hash_count + 1
- if job[1] == hash:
- soc.send(bytes(str(iJob) + "," + str(last_hash_count), encoding="utf8")) # Send result of hashing algorithm to pool
- while True:
- feedback = soc.recv(1024).decode()
- if feedback == "GOOD":
- now = datetime.datetime.now()
- shares[0] = shares[0] + 1 # Share accepted = increment feedback shares counter by 1
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "accepted: " + str(shares[0]) + "/" + str(shares[0] + shares[1]) + " (" + str(shares[0] / (shares[0] + shares[1]) * 100) + "%), diff: " + str(diff) + ", " + str(khash_count) + " khash/s (yay!!!)")
- break
- elif feedback == "BAD":
- now = datetime.datetime.now()
- shares[1] = shares[1] + 1 # Share rejected = increment bad shares counter by 1
- print(now.strftime("[%Y-%m-%d %H:%M:%S] ") + "rejected: " + str(shares[1]) + "/" + str(shares[1] + shares[1]) + " (" + str(shares[0] / (shares[0] + shares[1]) * 100) + "%), diff: " + str(diff) + ", " + str(khash_count) + " khash/s (boo!!!)")
- break
- time.sleep(0.025) # Try again if no response after 0.025 seconds
- break
-
diff --git a/README.md b/README.md
index e6e4f650..b0ec2911 100644
--- a/README.md
+++ b/README.md
@@ -1,136 +1,46 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Watch demo »
-
- Join our Discord
-
- View pool statistics
-
- Explore wikis
- •
- Report bugs
-
- Exchange DUCO to other cryptocurrency
-
-
-
-
-
-[](https://github.com/revoxhere/duino-coin/search?l=py)
-[](https://opensource.org/licenses/MIT)
-[](https://github.com/revoxhere/duino-coin/releases/tag/alpha-6.1)
-[](https://discord.gg/qa88ZYM)
-
-
-## Table of Contents
-
-* [About Duino-Coin](#about-the-project)
-* [News and FAQ](#news-and-faq)
-* [Prerequisites](#prerequisites)
-* [Getting Started](#getting-started)
-* [Contributing](#contributing)
-* [License](#license)
-* [Built With](#built-with)
-* [Authors](#authors)
-
-
-
-## About The Project
-
-
-
-
-
-There are many cryptocurrencies available. Most of them can be mined, but only using powerful CPUs, GPUs or ASICs to make some real money. There aren't many that support "normal" ways of mining.
-I've always wanted to do something related to cryptocurrencies with Arduino. Thats why I created Duino-Coin. Cryptocurrency that can be mined with regular home computers, smartphones (you can use app called [PyDroid](https://play.google.com/store/apps/details?id=ru.iiec.pydroid3) to run PC Miner), Arduino boards (you can find Arduino code in every [release](https://github.com/revoxhere/duino-coin/releases)) and much more in the future.
+##
-Generally, why should you mine Duino-Coin?
-* ~In the future, duino-coin may be worth something.~ 1 DUCO (Duino-Coin) is worth ~0.1 XMG (Coin Magi) at the time I'm writing this. You can exchange it [here](https://revoxhere.github.io/duco-exchange/).
-* Mining Duino-Coins isn't very CPU intensive.
-* It can be mined using various platforms.
-* Mining on regular computers and smartphones is profitable.
-* You will be able to proudly say that you supported my project :smile:
+
-Why would you want to mine on Arduino?
-* You may have some Arduino boards that don't do anything.
-* Watching Arduino do something useful that produces money is satisfying.
+##
-## News and FAQ
+Duino-Coin Master Server
-**News** about updates, future features and other things can be found at the [official blog](https://revoxhere.github.io/duino-coin/).
-Frequently Asked Questions (**FAQ**) can be found [here](https://revoxhere.github.io/duino-coin/faq)
-You can check **pool statistics** by visiting [this page](https://revoxhere.github.io/duco-statistics/).
+This branch of the Duino-Coin repository contains the source code of the master-server and documentation for it.
-## Prerequisites
-
-### Linux
-If you're using Linux, you need to download some dependencies:
-```bash
-sudo apt install python3 python-pip
-python -m pip install pyserial
-```
-### Windows
-If you're just a casual user and don't care about unstable stuff you don't need to install anything. Just grab latest [release](https://github.com/revoxhere/duino-coin/releases) and you're ready to go.
-
-## Getting Started
+## Contributing
+Contributions are welcome! If you'd like to help improve Duino-Coin, please check out our [Contribution Guide](CONTRIBUTING.md).
-Grab latest [release](https://github.com/revoxhere/duino-coin/releases) for your OS.
-Launch `Wallet` to register. Then you can login.
-After making an account, run `Miner` or `Arduino Miner` to mine Duino-Coins.
-Programs will display you all information and help you need.
+## License
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
-If you need detailed help about usage, installation or configuration, see our [Wikis](https://github.com/revoxhere/duino-coin/wiki).
-If you can't find what you need, open an [Issue](https://github.com/revoxhere/duino-coin/issues), we'll help in no time!
+## Branding
-
-## Contributing
+We suggest using these colors in creating DUCO-Related apps:
-Contributions are what make the open source community such an amazing place to be learn, inspire, and create.
-Any contributions you make are **greatly appreciated**.
+### Branding colors
-1. Fork the Project
-2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
-3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
-4. Push to the Branch (`git push origin feature/AmazingFeature`)
-5. Make sure everything works as intended
-6. Open a Pull Request :wink:
+* White accent: `#fafafa` 
+* Orange accent: `#ff4112` 
+* Sun yellow accent: `#ffb412` 
+* Magenta accent: `#f31291` 
+* Dark accent: `#121212` 
-
-## License
+Gradient variations of the colors above are a welcome touch.
-Distributed under the MIT License. See `LICENSE` for more information.
+#### GUI colors
+* Background: `#121212` (Dark)  or `#fffdee` (Light) 
+* Font color: `#fffdee` (Dark)  or `#0f0f0f` (Light) 
-### Built With
-This section briefly lists major frameworks that Duino-Coin uses:
-* [Python and IDLE](https://www.python.org) - programming,
-* [pySerial](https://pythonhosted.org/pyserial/) - Arduino and Python communication,
-* [Arduino IDE](https://www.arduino.cc) - Arduino programming and debugging,
-* [auto-py-to-exe](https://pypi.org/project/auto-py-to-exe/) - creating Windows executables,
-* [PyGithub](https://github.com/PyGithub/PyGithub) - pool statistics API integration,
-* [serveo](https://serveo.net) - hosting official pool.
+### Icons
-
-## Authors
+| | | |
+|:---:|:---:|:---:|
+|
|
|
|
+|
|
|
|
-* **Idea, lead programming:** [Robert "revox" Piotrowski](https://github.com/revoxhere/) - [YouTube](https://youtube.com/c/reVox96) - robik123.345@gmail.com
-* **Programming:** [MrKris7100](https://github.com/MrKris7100) - [YouTube](https://www.youtube.com/user/MrKris7100)
-* **Wikis & Social stuff:** [Jan "Furim" Malewski](https://github.com/Furim) - [YouTube](https://www.youtube.com/channel/UCKxFuOCalYxlQoS7R6zilRQ)
-* **[Artwork](https://i.imgur.com/ZRRGDjs.png):** [ATAR4XY](https://www.youtube.com/channel/UC-gf5ejhDuAc_LMxvugPXbg)
-* **Testing:** [Jan Malewski](https://www.youtube.com/channel/UCKxFuOCalYxlQoS7R6zilRQ), [MrKris7100](https://www.youtube.com/user/MrKris7100), [ATAR4XY](https://www.youtube.com/channel/UC-gf5ejhDuAc_LMxvugPXbg), Alina
+
+
+
-Project Link: [https://github.com/revoxhere/duino-coin/](https://github.com/revoxhere/duino-coin/)
-Tags (ignore): Duino Coin Coin Magi XMG DUCO Cryptocurrency Exchange Website Stocks Bitcoin Ethereum Litecoin Arduino AVR Rate Digital Cryptocoins
+More resources available in the [Resources folder](https://github.com/revoxhere/duino-coin/tree/master/Resources)
\ No newline at end of file
diff --git a/Server.py b/Server.py
deleted file mode 100644
index 973a827b..00000000
--- a/Server.py
+++ /dev/null
@@ -1,554 +0,0 @@
-#!/usr/bin/env python
-
-###########################################
-# Duino-Coin public-server version 0.6.3 #
-# https://github.com/revoxhere/duino-coin #
-# copyright by MrKris7100 & revox 2019 #
-###########################################
-# Important: this version of the server is a bit different than one used in "real" duino-coin network.
-# !!! If you want to host the pool/server yourself, you need to firstly install 'psutil' using pip install psutil !!!
-# !!! If you want to host the pool/server yourself, you need to firstly install 'PyGithub' using pip install PyGithub !!!
-
-VER = "0.6"
-
-import socket, threading, time, random, hashlib, math, datetime, re, configparser, sys, errno, os, psutil, string
-from pathlib import Path
-from github import Github
-
-def ServerLog(whattolog):
- #Getting actual date and time
- now = datetime.datetime.now()
- #Creating and opening today's log file
- logfile = open(now.strftime("logs/%Y-%m-%d.txt"), "a")
- #Time formating
- now = now.strftime("[%Y-%m-%d %H:%M:%S] ")
- #Writing message and closing file
- logfile.write(now + whattolog + "\n")
- logfile.close()
-
-def ServerLogHash(whattolog): #Separate serverlog section for mining section debugging. Not used in proper pool to reduce disk usage.
- #Getting actual date and time
- #now = datetime.datetime.now()
- #Creating and opening today's log file
- #logfile = open(now.strftime("logs/%Y-%m-%d.txt"), "a")
- #Time formating
- #now = now.strftime("[%Y-%m-%d %H:%M:%S] ")
- #Writing message and closing file
- #logfile.write(now + whattolog + "\n")
- #logfile.close()
- pass
-
-def UpdateServerInfo():
- global server_info, hashrates, threads, diff, update_count, gitrepo, gitusername
- now = datetime.datetime.now()
- now = now.strftime("%H:%M:%S")
- #Nulling pool hashrate stat
- server_info['pool_hashrate'] = 0
- #Counting registered users
- server_info['users'] = len(os.listdir('users'))
- #Addition miners hashrate and update pool's hashrate
- for hashrate in hashrates:
- server_info['pool_hashrate'] += hashrates[hashrate]["hashrate"]
- #Preparing json data for API
- data = {"pool_miners" : server_info["miners"], "pool_hashrate" : server_info["pool_hashrate"], "users" : server_info["users"], "miners" : {}}
- #Adding mining users to API's output
- for hashrate in hashrates:
- data["miners"][hashrate] = hashrates[hashrate]
- #Writing data to text API
- file = open("config/api.txt", "w")
- file.write(str("Pool hashrate: "))
- file.write(str(int((server_info['pool_hashrate']) / 1000)))
- file.write(str(" kH/s\n"))
- file.write(str("Pool workers: "))
- file.write(str(server_info["miners"]))
- file.write(str(" ("))
- file.write(str(' '.join([hashrates[x]["username"] for x in hashrates])))
- file.write(str(")\n"))
- with locker:
- blok = open("config/blocks", "r")
- bloki = blok.readline()
- file.write(str("Mined blocks: " + bloki))
- blok.close()
- file.write(str("\n"))
- file.write(str("Last block #: "))
- lastblok = open("config/lastblock", "r+")
- lastblokid = lastblok.readline().rstrip("\n\r ")[:10] + (lastblok.readline().rstrip("\n\r ")[10:] and '..')
- file.write(str(lastblokid))
- lastblok.close()
- file.write(str(" [...]"))
- file.write(str("\nCurrent difficulty: "))
- diff = math.ceil(int(bloki) / diff_incrase_per)
- file.write(str(diff))
- file.write(str("\nReward: "))
- file.write(str(reward))
- file.write(str(" DUCO/block"))
- file.write(str("\nDUCO/XMG: 9.82 (\/)"))
- file.write(str("\nLast updated: "))
- file.write(str(now))
- file.write(str(" (updated every 90s)"))
- file.close() #End of API file writing
- #Update api file on GitHub
- try: #Create new file if it doesn't exist
- repo.create_file("api.txt", "test", "test", branch="master")
- ServerLog("File didn't exist on GitHub repo, created it!")
- except:
- pass
- file_contents = Path("config/api.txt").read_text() #Get api file contents
- update_count = update_count + 1 #Increment update counter by 1
- repo = g.get_repo("revoxhere/"+gitrepo)
- contents = repo.get_contents("api.txt") #Get contents of previous file for SHA verification
- repo.update_file(contents.path, "Statistics update #"+str(update_count), str(file_contents), contents.sha, branch="master") #Post statistics file into github
- ServerLog("Updated statistics file on GitHub. Update count:"+str(update_count))
- #Wait 90 seconds and repeat
- threading.Timer(90, UpdateServerInfo).start()
-
-def randomString(stringLength=10):
- #Generating random string with specified length
- letters = string.ascii_lowercase
- return ''.join(random.choice(letters) for i in range(stringLength))
-
-class InputProc(threading.Thread):
- def run(self):
- proc = psutil.Process()
- while True:
- #Waiting for input command in server console
- cmd = input(">")
- #Parsing commands
- if cmd.find(" ") != -1:
- cmd = cmd.split(" ")
- if cmd[0] == "list":
- #Listing all registered users on screen
- if cmd[1] == "users":
- print(' '.join([os.path.splitext(x)[0] for x in os.listdir('users')]))
- #Listing all connected users on screen
- elif cmd[1] == "miners":
- print(' '.join([hashrates[x]["username"] for x in hashrates]))
- if cmd[0] == "kick":
- #Kick (disconnect) specified user
- kicklist.append(cmd[1])
- if cmd[0] == "ban":
- #Ban and kick specified user
- kicklist.append(cmd[1])
- #Just changing user's password to random string
- file = open("users/" + cmd[1] + ".txt", "w")
- file.write(randomString(32))
- file.close()
- else:
- if cmd == "kickall":
- #Kicking (disconnecting) all connected users
- kicklist.append(-1)
- if cmd == "serverinfo":
- #Displaying server's info like version, resource usage, etc.
- print("Duino-Coin server by revox & MrKris7100 from DUCO developers")
- print("Server version: " + VER)
- print("\nConnected GitHub account: "+str(gitusername)+", publishing on: "+str(gitrepo))
- print(" GitHub update count: "+str(update_count))
- print("\nServer resources usage:")
- print(" CPU usage: " + str(proc.cpu_percent()) + "%")
- print(" Memory usage: " + "{:.1f}".format(proc.memory_info()[0] / 2 ** 20) + "MB")
- print("\nConnected miners: " + str(server_info["miners"]))
- print("Server hashrate: " + str(server_info["pool_hashrate"]) + " H/s")
- print("Registered users count: " + str(server_info["users"]))
- with locker:
- file = open("config/blocks", "r")
- print("\nMined blocks count: " + file.readline())
- file.close()
- file = open("config/lastblock", "r+")
- print("Last block hash: " + file.readline())
- file.close()
- if cmd == "stop":
- #Shutting down server
- with locker:
- sys.exit()
-
-class ClientThread(threading.Thread): #separate thread for every user
- def __init__(self, ip, port, clientsock):
- threading.Thread.__init__(self)
- self.ip = ip
- self.port = port
- self.clientsock = clientsock
- try:
- #Sending server version to client
- clientsock.send(bytes(VER, encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- err = True
- def run(self):
- err = False
- global server_info, hashrates, kicklist, thread_id, diff
- #New user connected
- username = ""
- #Getting thread id for this connection
- thread_id = str(threading.current_thread().ident)
- ServerLog("New thread (" + thread_id + ") started, connection: " + self.ip + ":" + str(self.port))
- while True:
- #Checking "kicklist" for "kickall" command
- if -1 in kicklist:
- del kicklist[:]
- break
- #Checking "kicklist" for this user "kick" command
- elif username in kicklist:
- kicklist.remove(username)
- break
- try:
- #Listening for requests from client
- data = self.clientsock.recv(1024)
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- try:
- data = data.decode()
- data = data.split(",")
- except:
- pass
-
- #Recived register request
- if data[0] == "REGI":
- username = data[1]
- password = data[2]
- server_info['miners'] += 1
- hashrates[thread_id] = {"username" : username, "hashrate" : 0}
- ServerLog("Client "+str(username)+" has requested account registration.")
- #Checking username for unallowed characters
- if re.match(regex,username):
- #Checking if user already exists
- if not Path("users/" + username + ".txt").is_file():
- #If user dosen't exist, saving his password and setting up balance
- file = open("users/" + username + ".txt", "w")
- file.write(password)
- file.close()
- file = open("balances/" + username + ".txt", "w")
- file.write(str(new_user_balance))
- file.close
- self.clientsock.send(bytes("OK", encoding='utf8'))
- ServerLog("New user (" + username + ") registered")
- else:
- #User arleady exists
- ServerLog("Account already exists!")
- self.clientsock.send(bytes("NO", encoding='utf8'))
- break
- else:
- #User used unallowed characters, disconnecting
- ServerLog("Unallowed characters!!!")
- self.clientsock.send(bytes("NO", encoding='utf8'))
- break
-
- #Recived login request
- elif data[0] == "LOGI": #login
- username = data[1]
- password = data[2]
- server_info['miners'] += 1
- hashrates[thread_id] = {"username" : username, "hashrate" : 0}
- ServerLog("Client request logging in to account " + username)
- #Checking username for unallowed characters
- if re.match(regex,username):
- #Checking that user exists
- try:
- #User exists, reading his password
- file = open("users/" + username + ".txt", "r")
- data = file.readline()
- file.close()
- except:
- #Doesnt exist, disconnect
- ServerLog("User doesn't exist!")
- self.clientsock.send(bytes("NO", encoding='utf8'))
- break
- #Comparing saved password with recived password
- if password == data:
- #Password matches
- self.clientsock.send(bytes("OK", encoding='utf8'))
- ServerLog("Password matches, user logged")
- #Updating statistics username
- hashrates[thread_id]["username"] = username
- else:
- #Bad password, disconneting
- ServerLog("Incorrect password")
- self.clientsock.send(bytes("NO", encoding='utf8'))
- break
- else:
- #User doesn't exists
- ServerLog("User doesn't exist!")
- self.clientsock.send(bytes("NO", encoding='utf8'))
- break
-
- #Client requested new job for him
- elif username != "" and data[0] == "JOB": #main, mining section
- ServerLog("New job for user: " + username)
- #Waiting for unlocked files then locking them
- with locker:
- #Reading blocks amount
- file = open("config/blocks", "r")
- blocks = int(file.readline())
- file.close()
- #Reading lastblock's hash
- file = open("config/lastblock", "r+")
- lastblock = file.readline()
- #Calculating difficulty
- diff = math.ceil(blocks / diff_incrase_per)
- rand = random.randint(0, 100 * diff)
- #Generating next block hash
- hashing = hashlib.sha1(str(lastblock + str(rand)).encode("utf-8"))
- ServerLogHash("Sending target hash: " + hashing.hexdigest())
- try:
- #Sending target hash to miner
- self.clientsock.send(bytes(lastblock + "," + hashing.hexdigest() + "," + str(diff), encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- #Updating lastblock's hash
- file.seek(0)
- file.write(hashing.hexdigest())
- file.truncate()
- file.close()
- try:
- #Waiting until client solves hash
- response = self.clientsock.recv(1024).decode()
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- #0.5.1 version compatibility
- if response.find(",") != -1:
- try:
- response = response.split(",")
- result = response[0]
- hashrates[thread_id]["hashrate"] = int(response[1])
- except:
- pass
- else:
- try:
- result = response
- hashrates[thread_id]["hashrate"] = 1000 #1kH/s if none submitted
- except:
- pass
- #Checking recived result is good hash
- if result == str(rand):
- ServerLogHash("Recived good result (" + str(result) + ")")
- #Rewarding user for good hash
- with locker: #Using locker because some users submitted problems when mining on many devices and weird things happened
- bal = open("balances/" + username + ".txt", "r")
- balance = str(float(bal.readline())).rstrip("\n\r ")
- balance = float(balance) + float(reward)
- bal = open("balances/" + username + ".txt", "w")
- bal.seek(0)
- bal.write(str(balance))
- bal.truncate()
- bal.close()
- try:
- self.clientsock.send(bytes("GOOD", encoding="utf8"))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- #Waiting fo unlocked files then lock them
- with locker:
- #Update amount of blocks
- blocks+= 1
- blo = open("config/blocks", "w")
- blo.seek(0)
- blo.write(str(blocks))
- blo.truncate()
- blo.close()
- else:
- #Recived hash is bad
- ServerLogHash("Recived bad result (" + str(result[0]) + ")")
- try:
- self.clientsock.send(bytes("BAD", encoding="utf8"))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
-
- #Client requested account balance checking
- elif username != "" and data[0] == "BALA": #check balance section
- ServerLog("Client request balance check")
- file = open("balances/" + username + ".txt", "r")
- balance = file.readline()
- file.close()
- try:
- self.clientsock.send(bytes(balance, encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
-
- #Close connection request, may be used in the future
- elif username != "" and data[0] == "CLOSE":
- try:
- ServerLog("Client requested thread (" + thread_id + ") closing")
- print("Klouz")
- #Closing socket connection
- self.clientsock.close()
- #Decrasing number of connected miners
- server_info['miners'] -= 1
- #Delete this miner from statistics
- del hashrates[thread_id]
- except:
- ServerLog("Error closing connection (" + thread_id + ")!")
-
- elif username != "" and data[0] == "SEND": #sending funds section
- sender = username
- reciver = data[2]
- amount = float(data[3])
- ServerLog("Client request transfer funds")
- #now we have all data needed to transfer money
- #firstly, get current amount of funds in bank
- try:
- file = open("balances/" + sender + ".txt", "r+")
- balance = float(file.readline())
- except:
- ServerLog("Can't checks sender's (" + sender + ") balance")
- #verify that the balance is higher or equal to transfered amount
- if amount > balance:
- try:
- self.clientsock.send(bytes("Error! Your balance is lower than amount you want to transfer!", encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- else: #if ok, check if recipient adress exists
- if Path("balances/" + reciver + ".txt").is_file():
- #it exists, now -amount from sender and +amount to reciver
- try:
- #remove amount from senders' balance
- balance -= amount
- file.seek(0)
- file.write(str(balance))
- file.truncate()
- file.close
- #get recipients' balance and add amount
- file = open("balances/" + reciver + ".txt", "r+")
- reciverbal = float(file.readline())
- reciverbal += amount
- file.seek(0)
- file.write(str(reciverbal))
- file.truncate()
- file.close()
- try:
- self.clientsock.send(bytes("Successfully transfered funds!!!", encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- ServerLog("Transferred " + str(amount) + " DUCO from " + sender + " to " + reciver)
- except:
- try:
- self.clientsock.send(bytes("Unknown error occured while sending funds.", encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- else: #message if recipient doesn't exist
- ServerLog("The recepient", reciver, "doesn't exist!")
- try:
- self.clientsock.send(bytes("Error! The recipient doesn't exist!", encoding='utf8'))
- except socket.error as err:
- if err.errno == errno.ECONNRESET:
- break
- try:
- ServerLog("Thread (" + thread_id + ") and connection closed")
- #Closing socket connection
- self.clientsock.close()
- #Decrasing number of connected miners
- server_info['miners'] -= 1
- #Delete this miner from statistics
- del hashrates[thread_id]
- except:
- ServerLog("Error closing connection (" + thread_id + ")!")
-
-
-regex = r'^[\w\d_()]*$'
-tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-threads = []
-kicklist = []
-server_info = {'miners' : 0, 'pool_hashrate' : 0, 'users' : 0}
-hashrates = {}
-config = configparser.ConfigParser()
-locker = threading.Lock()
-update_count = 0
-
-#Initial files and folders checking and making
-if not Path("logs").is_dir():
- os.mkdir("logs")
-if not Path("config").is_dir():
- os.mkdir("config")
-if not Path("users").is_dir():
- os.mkdir("users")
-if not Path("balances").is_dir():
- os.mkdir("balances")
-if not Path("config/lastblock").is_file():
- file = open("config/lastblock", "w")
- file.write(hashlib.sha1(str("revox.heremrkris7100").encode("utf-8")).hexdigest()) #First block
- file.close()
-if not Path("config/blocks").is_file():
- file = open("config/blocks", "w")
- file.write("1")
- file.close()
-#Initial configuration
-if not Path("config/config.ini").is_file():
- print("Initial server configuration\n")
- host = input("Enter server host adddress: ")
- port = input("Enter server port: ")
- new_user_balance = input("Enter default balance for new users: ")
- reward = input("Enter default block reward: ")
- diff_incrase_per = input("Enter how many blocks are needed for incrase difficulty: ")
- gitusername = input("Enter GitHub username to push api: ")
- gitpassword = input("Enter GitHub password to push api: ")
- gitrepo = input("Enter GitHub repository name to push api: ")
- config['server'] = {"host": host,
- "port": port,
- "new_user_bal": new_user_balance,
- "reward": reward,
- "diff_incrase_per": diff_incrase_per,
- "gitusername": gitusername,
- "gitpassword": gitpassword,
- "gitrepo": gitrepo}
- with open("config/config.ini", "w") as configfile:
- config.write(configfile)
-#Loading server config from INI if exists
-else:
- config.read("config/config.ini")
- host = config['server']['host']
- port = config['server']['port']
- new_user_balance = config['server']['new_user_bal']
- reward = config['server']['reward']
- diff_incrase_per = config['server']['diff_incrase_per']
- gitusername = config['server']['gitusername']
- gitpassword = config['server']['gitpassword']
- gitrepo = config['server']['gitrepo']
- ServerLog("Loaded server config: " + host + ", " + port + ", " + new_user_balance + ", " + reward + ", " + diff_incrase_per)
-#Converting some variables to numbers
-port = int(port)
-reward = float(reward)
-diff_incrase_per = int(diff_incrase_per)
-#Binding socket
-try:
- tcpsock.bind((host, port))
- ServerLog("TCP server started...")
-except:
- ServerLog("Error during TCP socket!")
- time.sleep(5)
- sys.exit()
-#Logging in to GitHub
-try:
- g = Github(gitusername, gitpassword)
- ServerLog("Logged in to GitHub...")
-except:
- ServerLog("Error logging in to GitHub!")
- time.sleep(5)
- sys.exit()
-#Thread for updating server info api
-UpdateServerInfo()
-#Main server Loop
-ServerLog("Listening for incoming connections...")
-while True:
- #Starting thread for input procesing
- newthread = InputProc()
- newthread.start()
- try:
- #Listening for new connections
- tcpsock.listen(16)
- (conn, (ip, port)) = tcpsock.accept()
- #Starting thread for new connection
- newthread = ClientThread(ip, port, conn)
- newthread.start()
- threads.append(newthread)
- except:
- ServerLog("Error in main loop!")
-
-for t in threads:
- t.join()
diff --git a/Unofficial miners/AutoIT Miner.au3 b/Unofficial miners/AutoIT Miner.au3
deleted file mode 100644
index 9f0e7e61..00000000
--- a/Unofficial miners/AutoIT Miner.au3
+++ /dev/null
@@ -1,109 +0,0 @@
-; ###########################################
-; # Duino-Coin miner version 0.4 #
-; # https://github.com/revoxhere/duino-coin #
-; # copyright by MrKris7100 2019 #
-; ###########################################
-
-#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
-#AutoIt3Wrapper_Change2CUI=y
-#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
-#include
-Global $shares[2], $socket, $last_hash_count = 0, $hash_Count = 0, $pool_address, $pool_port, $username, $password
-If Not FileExists(@ScriptDir & "\config.ini") Then
- ConsoleWrite("Initial configuration, you can edit 'config.ini' later" & @CRLF & @CRLF)
- ConsoleWrite("Enter pool adddress (official: serveo.net): ")
- $pool_address = Cin()
- IniWrite(@ScriptDir & "\config.ini", "pool", "address", $pool_address)
- ConsoleWrite("Enter pool port (official: 14808): ")
- $pool_port = Cin()
- IniWrite(@ScriptDir & "\config.ini", "pool", "port", $pool_port)
- ConsoleWrite("Enter username: ")
- $username = Cin()
- IniWrite(@ScriptDir & "\config.ini", "pool", "username", $username)
- ConsoleWrite("Enter password: ")
- $password = Cin()
- IniWrite(@ScriptDir & "\config.ini", "pool", "password", $password)
-Else
- $pool_address = IniRead(@ScriptDir & "\config.ini", "pool", "address", "0")
- $pool_port = IniRead(@ScriptDir & "\config.ini", "pool", "port", "0")
- $username = IniRead(@ScriptDir & "\config.ini", "pool", "username", "0")
- $password = IniRead(@ScriptDir & "\config.ini", "pool", "password", "0")
-EndIf
-TCPStartup()
-While 1
- ConsoleWrite("Connecting to pool..." & @CRLF)
- $socket = TCPConnect(TCPNameToIP($pool_address), $pool_port)
- If @error Then
- ConsoleWrite(@error & " Cannot connect to pool server. Retrying in 30 seconds..." & @CRLF)
- Sleep(30000)
- Else
- ConsoleWrite("Connected!" & @CRLF)
- ExitLoop
- EndIf
- Sleep(25)
-WEnd
-ConsoleWrite("Logging in..." & @CRLF)
-TCPSend($socket, "LOGI," & $username & "," & $password)
-While 1
- $resp = TCPRecv($socket, 1024)
- If $resp = "OK" Then
- ConsoleWrite("Logged in!" & @CRLF)
- ExitLoop
- EndIf
- If $resp = "NO" Then
- ConsoleWrite("Error, closing in 5 seconds...")
- TCPCloseSocket($socket)
- Sleep(5000)
- Exit
- EndIf
- Sleep(25)
-WEnd
-ConsoleWrite("Start mining..." & @CRLF)
-AdlibRegister("hush", 1000)
-While 1
- TCPSend($socket, "JOB")
- While 1
- $job = TCPRecv($socket, 1024)
- If $job Then ExitLoop
- Sleep(25)
- WEnd
- $job = StringSplit($job, ",", 2)
- ConsoleWrite("Recived new job from pool. Diff: " & $job[2] & @CRLF)
- For $iJob = 0 To 100 * $job[2]
- $hash = StringLower(StringTrimLeft(_Crypt_HashData($job[0] & $iJob, 0x00008004), 2))
- $hash_count += 1
- If $job[1] = $hash Then
- TCPSend($socket, StringToBinary($iJob, 4))
- While 1
- $good = TCPRecv($socket, 1024)
- If $good = "GOOD" Then
- $shares[0] += 1 ; Share accepted
- ConsoleWrite("Share accepted " & $shares[0] & "/" & $shares[0] + $shares[1] & " (" & StringLeft($shares[0] / ($shares[0] + $shares[1]) * 100, 4) & "%), " & $last_hash_count & " H/s" & @CRLF)
- ExitLoop
- ElseIf $good = "BAD" Then
- $shares[1] += 1 ; SHare rejected
- ConsoleWrite("Share rejected " & $shares[0] & "/" & $shares[0] + $shares[1] & " (" & StringLeft($shares[0] / ($shares[0] + $shares[1]) * 100, 4) & "%), " & $last_hash_count & " H/s" & @CRLF)
- ExitLoop
- EndIf
- Sleep(25)
- WEnd
- ExitLoop
- EndIf
- Next
-WEnd
-Func hush()
- $last_hash_count = $hash_count
- $hash_count = 0
-EndFunc
-func Cin()
- Local $sResult
- Local $sText
- While True
- $sText = ConsoleRead()
- If @error Then ExitLoop
- if StringRight($sText, 1) = @LF then
- Return StringTrimRight($sText, 1)
- EndIf
- Sleep(20)
- WEnd
-EndFunc
diff --git a/Unofficial miners/Disclaimer.txt b/Unofficial miners/Disclaimer.txt
deleted file mode 100644
index aa19912c..00000000
--- a/Unofficial miners/Disclaimer.txt
+++ /dev/null
@@ -1 +0,0 @@
-Warning: use of these miners is not supported by us if something doesn't work or goes wrong. These are mainly maintained by commmunity.
diff --git a/Wallet.py b/Wallet.py
deleted file mode 100644
index 625e9d4e..00000000
--- a/Wallet.py
+++ /dev/null
@@ -1,294 +0,0 @@
-#!/usr/bin/env python
-
-###########################################
-# Duino-Coin wallet version 0.6.1 alpha #
-# https://github.com/revoxhere/duino-coin #
-# copyright by revox 2019 #
-###########################################
-
-import time, socket, sys, os, configparser, tkinter, webbrowser
-import threading
-from tkinter import messagebox
-from tkinter import *
-from pathlib import Path
-
-#setting variables
-users = {}
-status = ""
-host = 'serveo.net' #official server ip
-port = 14808 #official server port
-s = socket.socket()
-config = configparser.ConfigParser()
-
-def Signup(): #signup definition
- global pwordE
- global pwordconfirm
- global nameE
- global roots
- window.destroy()
- roots = Tk() #register window
- roots.resizable(False, False)
- roots.title('Register')
-
- nameL = Label(roots, text='Username: ')
- pwordL = Label(roots, text='Password: ')
- pwordconfirm = Label(roots, text='Confirm Password: ')
- nameL.grid(row=1, column=0, sticky=W)
- pwordL.grid(row=2, column=0, sticky=W)
- pwordconfirm.grid(row=3, column=0, sticky=W)
-
- nameE = Entry(roots)
- pwordE = Entry(roots, show='*')
- pwordconfirm = Entry(roots, show='*')
- nameE.grid(row=1, column=1)
- pwordE.grid(row=2, column=1)
- pwordconfirm.grid(row=3, column=1)
-
- signupButton = Button(roots, text='Register account', command=FSSignup)
- signupButton.grid(columnspan=2, sticky=W)
- roots.mainloop()
- SelectScr()
-
-def FSSignup(): #signup server communication section
- username = nameE.get()
- passwordconfirm = pwordconfirm.get()
- password = pwordE.get()
- if password == passwordconfirm:
- s.send(bytes("REGI,"+username+","+password, encoding='utf8')) #send register request to server
- key = s.recv(3)
- key=key.decode()
- time.sleep(0.025)
- key = s.recv(2)
- key = key.decode()
- if key == "OK":
- messagebox.showinfo("Success!", "Successfully registered user "+username+".\nRestart your wallet and login.")
- roots.destroy()
- while True:
- time.sleep(99)
- if key == "NO":
- messagebox.showerror("Error!", "User "+username+" is already registered or you've used non-allowed characters!\nPlease try again!")
- roots.destroy()
- Signup()
- else:
- roots.destroy()
- Signup()
-
-def Login(): #login window
- window.destroy()
- global nameEL
- global pwordEL
- global rootA
-
- rootA = Tk() #login window
- rootA.resizable(False, False)
- rootA.title('Login')
-
- nameL = Label(rootA, text='Username: ')
- pwordL = Label(rootA, text='Password: ')
- nameL.grid(row=1, sticky=W)
- pwordL.grid(row=2, sticky=W)
-
- nameEL = Entry(rootA)
- pwordEL = Entry(rootA, show='*')
- nameEL.grid(row=1, column=1)
- pwordEL.grid(row=2, column=1)
-
- loginB = Button(rootA, text='Login to account', command=CheckLogin)
- loginB.grid(columnspan=2, sticky=W)
-
- rootA.mainloop()
- SelectScr()
-
-def CheckLogin(): #login server communication section
- username = nameEL.get()
- password = pwordEL.get()
- s.send(bytes("LOGI,"+username+","+password, encoding='utf8')) #send login request to server
-
- key = s.recv(3)
- time.sleep(0.025)
- key = s.recv(2)
- key = key.decode()
- if key == "OK":
- messagebox.showinfo("Success", "Successfully logged in!\nYour login data will be automatically remembered!\nPlease restart your wallet.")
- config['wallet'] = {"username": username,
- "password": password}
- with open("WalletConfig.ini", "w") as configfile:
- config.write(configfile)
- rootA.destroy()
- WalletScr()
-
- if key == "NO":
- messagebox.showerror("Error!", "Incorrect credentials!\n Please try again!")
- rootA.destroy()
- Login()
-
- Login()
-
-def SelectScr(): #first-time launch window
- global window
- window = tkinter.Tk()
- window.geometry("355x200")
- window.resizable(False, False)
- window.title("Duino-Coin wallet")
-
- label = tkinter.Label(window, text = "").pack()
- label = tkinter.Label(window, text = " Welcome to the Duino-Coin wallet!", font="-weight bold").pack()
- label = tkinter.Label(window, text = " It looks like it's your first time launching this program. ").pack()
- label = tkinter.Label(window, text = " Do you have an Duino-Coin account?").pack()
- label = tkinter.Label(window, text = "").pack()
- tkinter.Button(window, text = " Yes, login me! ", command = Login).pack()
- tkinter.Button(window, text = " No, register me!", command = Signup).pack()
- label = tkinter.Label(window, text = "").pack()
- label = tkinter.Label(window, text = " 2019 Duino-Coin developers").pack()
-
- window.mainloop()
-
-def WalletScr():
- global username
- print("Using pre-defined settings")
- config.read("WalletConfig.ini")
- username = config["wallet"]["username"]
- password = config["wallet"]["password"]
- print("Pre-defined settings:", username, password)
-
- s.send(bytes("LOGI,"+username+","+password, encoding='utf8'))
- key = s.recv(3)
- time.sleep(0.025)
- key = s.recv(2)
- key=key.decode()
- print(key)
- if key == "OK":
- print("ok")
- WalletWindow()
- if key == "NO":
- messagebox.showerror("Error!","Error in pre-defined credentials!\nRemoving them and again starting login select window")
- os.remove("WalletConfig.ini")
- SelectScr()
-
-def FSSSend():
- global receipent
- global fsssend
- global amount
- sendit = "OK"
- receipent = receipentA.get()
- amount = amountA.get()
-
- if amount.isupper() or amount.islower():
- sendit = "NO"
- print("Amount contains letters!")
- messagebox.showerror("Error!","Incorrect amount!")
- send.destroy()
- if amount == "0":
- sendit = "NO"
- print("Can't send 0!")
- messagebox.showerror("Error!","Incorrect amount!")
- send.destroy()
- if sendit =="OK":
- print("Sending ", amount, " funds from:", username, "to", receipent)
- s.send(bytes("SEND,"+username+","+receipent+","+amount, encoding='utf8')) #send sending funds request to server
- time.sleep(0.1)
- message = s.recv(1024).decode('utf8')
- message = ''.join([i for i in message if not i.isdigit()]) #data formatting
- messagebox.showinfo("Server message", message) #print server message
- WalletWindow()
- send.destroy()
- else:
- WalletWindow()
- send.destroy()
-
-def Send():
- global amountA
- global receipentA
- global send
- send = Tk() #sending funds window
- send.resizable(False, False)
- send.title('Send funds')
-
- label = tkinter.Label(send, text = "Your balance: "+balance+" DUCO")
- receipentA = Label(send, text="Receipents' username: ")
- amountA = Label(send, text='Amount: ')
- receipentA.grid(row=1, column=0, sticky=W)
- amountA.grid(row=2, column=0, sticky=W)
- label.grid(row=0, column=0, sticky=W)
-
- receipentA = Entry(send)
- amountA = Entry(send)
- receipentA.grid(row=1, column=1)
- amountA.grid(row=2, column=1)
-
-
- signupButton = Button(send, text='Send funds', command=FSSSend)
- signupButton.grid(columnspan=2, sticky=W)
- send.mainloop
-
-def Receive(): #receiving funds help dialog
- messagebox.showinfo("Receive funds", "To receive funds, instruct others to send money to your username ("+username+").")
- pass
-
-def About():
- global about
-
- about = Tk() #about window
- about.resizable(False, False)
- about.geometry("300x100")
- about.title('About')
-
- label = tkinter.Label(about, text = "Official Duino-Coin wallet", font="-weight bold").pack()
- label = tkinter.Label(about, text = "Wallet version: 0.6.1 alpha").pack()
- label = tkinter.Label(about, text = "Made by revox from Duino-Coin developers").pack()
- label = tkinter.Label(about, text = "Learn more at: github.com/revoxhere/duino-coin").pack()
-
-def Exchange():
- webbrowser.open_new_tab("https://revoxhere.github.io/duco-exchange/")
- pass
-
-def getBalance():
- global balance
- s.send(bytes("BALA", encoding='utf8'))
- time.sleep(0.025)
- balance = s.recv(6)
- balance = balance.decode('utf8')
- print("Got balance from server:", balance)
-
-
-def WalletWindow():
- getBalance()
- global wallet
-
- print("Displaying main wallet window")
- wallet = tkinter.Tk()
- wallet.geometry("320x250")
- wallet.resizable(False, False)
- wallet.title("Duino-Coin wallet")
-
- label = tkinter.Label(wallet, text = "Official Duino-Coin wallet", font="-weight bold").place(relx=.5, rely=.09, anchor="c")
- label = tkinter.Label(wallet, text = "").grid()
- label = tkinter.Label(wallet, text = "Your balance: "+balance+" (DUCO)").place(relx=.5, rely=.2, anchor="c")
-
- tkinter.Button(wallet, text = " Send funds ", command = Send).place(relx=0.355, rely=0.30)
- tkinter.Button(wallet, text = " Receive funds ", command = Receive).place(relx=0.353, rely=0.45)
- tkinter.Button(wallet, text = " Exchange DUCO ", command = Exchange).place(relx=0.35, rely=0.60)
- tkinter.Button(wallet, text = " About ", command = About).place(relx=0.35, rely=0.75)
-
- label = tkinter.Label(wallet, text = "2019 Duino-Coin developers").place(relx=0.46, rely=0.91)
-
- wallet.mainloop()
-
-def Start():
- try:
- s.connect((host, port))
- print("Connected to the server")
- if not Path("WalletConfig.ini").is_file():
- SelectScr()
- else:
- WalletScr()
- except:
- root = tkinter.Tk()
- root.withdraw()
- messagebox.showerror("Error!","Server communication failed!\nA server update is probably underway.\nPlease try again in a couple of hours.")
- sys.exit()
-
-Start()
-
-
-
diff --git a/assets/Banner.jpg b/assets/Banner.jpg
new file mode 100644
index 00000000..c3d7e51b
Binary files /dev/null and b/assets/Banner.jpg differ
diff --git a/assets/file-structure.png b/assets/file-structure.png
new file mode 100644
index 00000000..f196eaef
Binary files /dev/null and b/assets/file-structure.png differ
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..e5f9a4f2
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,25 @@
+services:
+ postgres:
+ image: postgres:15-alpine
+ container_name: duco_db
+ restart: unless-stopped
+ environment:
+ POSTGRES_DB: duco
+ POSTGRES_USER: duco
+ POSTGRES_PASSWORD: duco
+ PGDATA: /var/lib/postgresql/data/pgdata
+ ports:
+ - "5432:5432"
+ volumes:
+ - ./db:/var/lib/postgresql
+ networks:
+ - backend_net
+ healthcheck:
+ test: [ "CMD-SHELL", "pg_isready -U postgres" ]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+networks:
+ backend_net:
+ driver: bridge
diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md
new file mode 100644
index 00000000..ead29a48
--- /dev/null
+++ b/docs/STRUCTURE.md
@@ -0,0 +1,43 @@
+## File Structure
+
+```
+master_server/
+├── docs/
+├── src/
+│ ├── cli/
+│ ├── config/
+│ ├── db/
+│ ├── mining/
+│ ├── pool/
+│ ├── server/
+│ ├── repository/
+│ ├── statistics/
+│ ├── cron/
+│ ├── types/
+│ └── main.rs
+```
+
+
+---
+
+## Module Overview
+
+| Module | Responsibility |
+|-----------------|----------------|
+| `cli` | Command-line interface to manage the server |
+| `config` | Loading and managing configuration (TOML) |
+| `db` | PostgreSQL connection, migrations |
+| `mining` | Difficulty calculation, rewards, and share verification |
+| `pool` | Pool management: login, work synchronization, logout |
+| `server` | TCP server |
+| `repository` | Data access abstraction, interacts with `db` |
+| `statistics` | Global pool and per-user statistics |
+| `cron` | Scheduled tasks: reward distribution, statistics cleanup |
+| `types` | Data types, structs, enums, and constants |
+| `main.rs` | Initializes configuration, logging, database, and starts server and cron jobs |
+
+---
+
+## Dependency Diagram
+
+
\ No newline at end of file
diff --git a/lefthook.yml b/lefthook.yml
new file mode 100644
index 00000000..18af43a2
--- /dev/null
+++ b/lefthook.yml
@@ -0,0 +1,34 @@
+pre-commit:
+ parallel: true
+ jobs:
+ - name: cargo fmt
+ run: cargo fmt --all -- --check
+ - name: cargo clippy
+ run: cargo clippy --all-targets --all-features -- -D warnings
+
+prepare-commit-msg:
+ commands:
+ conventional-commits-prepare:
+ tags: commit-msg
+ run: |
+ echo '[note] Use conventional commits: (optional scope): short description'
+ echo '[note] Do not use emojis'
+ echo '[note] Do not use long messages'
+
+commit-msg:
+ commands:
+ conventional-commits:
+ tags: commit-msg
+ run: bash scripts/validate-commit-msg.sh "$@"
+ fail_text: "Commit message doesn't follow Conventional Commits specification."
+
+colors: true
+no_tty: false
+source_dir: ".lefthook"
+source_dir_local: ".lefthook-local"
+
+output:
+ - execution
+ - execution_out
+ - execution_info
+ - skips
diff --git a/scripts/validate-commit-msg.sh b/scripts/validate-commit-msg.sh
new file mode 100644
index 00000000..7ff10cb7
--- /dev/null
+++ b/scripts/validate-commit-msg.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+commit_msg=""
+if [[ -n "${1:-}" && -f "$1" ]]; then
+ commit_msg="$(head -n 1 "$1" | tr -d '\r\n')"
+fi
+
+if [[ -z "$commit_msg" && -n "${LEFTHOOK_COMMIT_MSG:-}" ]]; then
+ commit_msg="$(printf '%s' "$LEFTHOOK_COMMIT_MSG" | head -n 1 | tr -d '\r\n')"
+fi
+
+if [[ -z "$commit_msg" && -f .git/COMMIT_EDITMSG ]]; then
+ commit_msg="$(head -n 1 .git/COMMIT_EDITMSG | tr -d '\r\n')"
+fi
+
+if [[ -z "$commit_msg" ]] || printf '%s' "$commit_msg" | grep -qE '^#'; then
+ printf '[warn] empty commit message, skipping check.\n'
+ exit 0
+fi
+
+printf '[check] checking commit: "%s"\n' "$commit_msg"
+
+if ! printf '%s' "$commit_msg" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|git)(\([^)]+\))?: .{1,72}$'; then
+ printf '[fail] invalid commit message format, spec: \n'
+ printf 'use: (optional scope): short description\n'
+ printf 'valid types: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test, git\n'
+ printf 'your message: "%s"\n' "$commit_msg"
+ exit 1
+fi
+
+if (( ${#commit_msg} > 128 )); then
+ printf '[fail] commit message too long, max 128 chars.\n'
+ printf 'actual length: %d\n' ${#commit_msg}
+ printf 'your message: "%s"\n' "$commit_msg"
+ exit 1
+fi
+
+description="$(printf '%s' "$commit_msg" | sed -E 's/^[a-z]+(\([^)]+\))?: //')"
+if printf '%s' "$description" | grep -qE '^(add|fix|update|change|remove|create)'; then
+ printf '[warn] good style in imperative: add, fix, update, etc.\n'
+ printf 'your message: "%s"\n' "$commit_msg"
+fi
+
+printf '[ok] commit message is valid.\n'
diff --git a/src/cli/app.rs b/src/cli/app.rs
new file mode 100644
index 00000000..1c3d7d36
--- /dev/null
+++ b/src/cli/app.rs
@@ -0,0 +1,104 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+use std::time::Instant;
+use sysinfo::System;
+
+pub struct App {
+ pub server_connections: u32,
+ pub server_rps: f64,
+ pub server_errors: u32,
+ pub server_data_up: u64,
+ pub server_data_down: u64,
+
+ pub pool_workers: u32,
+ pub pool_hashrate: f64,
+ pub pool_blocks: u32,
+ pub pool_shares_good: u32,
+ pub pool_shares_bad: u32,
+
+ pub users_active: u32,
+ pub users_total: u32,
+ pub users_new_today: u32,
+ pub users_verified: u32,
+
+ pub logs: Vec,
+ pub input: String,
+
+ pub sys: System,
+ pub cpu_usage: Vec,
+ pub mem_usage: Vec,
+
+ pub connections: Vec,
+
+ pub last_tick: Instant,
+ pub should_quit: bool,
+}
+
+pub struct ConnectionInfo {
+ pub name: String,
+ pub ip: String,
+ pub port: u16,
+ pub status: String,
+ pub sent: String,
+ pub received: String,
+ pub uptime: String,
+}
+
+impl Default for App {
+ fn default() -> Self {
+ let sys = System::new();
+
+ Self {
+ sys,
+ server_connections: 0,
+ server_rps: 0.0,
+ server_errors: 0,
+ server_data_up: 0,
+ server_data_down: 0,
+
+ pool_workers: 0,
+ pool_hashrate: 0.0,
+ pool_blocks: 0,
+ pool_shares_good: 0,
+ pool_shares_bad: 0,
+
+ users_active: 0,
+ users_total: 0,
+ users_new_today: 0,
+ users_verified: 0,
+
+ logs: vec!["TCP Server Listening on 127.0.0.1:4000".to_string()],
+ input: String::new(),
+
+ cpu_usage: vec![0.0; 20],
+ mem_usage: vec![0.0; 20],
+
+ connections: Vec::new(),
+
+ last_tick: Instant::now(),
+ should_quit: false,
+ }
+ }
+}
+
+impl App {
+ pub fn on_tick(&mut self) {
+ self.sys.refresh_cpu_usage();
+ self.sys.refresh_memory();
+
+ self.cpu_usage.remove(0);
+ self.cpu_usage.push(self.sys.global_cpu_usage() as f64);
+
+ self.mem_usage.remove(0);
+ self.mem_usage
+ .push(self.sys.used_memory() as f64 / self.sys.total_memory() as f64 * 100.0);
+ }
+}
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
new file mode 100644
index 00000000..bd671521
--- /dev/null
+++ b/src/cli/mod.rs
@@ -0,0 +1,95 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+pub mod app;
+pub mod ui;
+
+pub use app::App;
+
+use crossterm::{
+ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind},
+ execute,
+ terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
+};
+use ratatui::{Terminal, backend::CrosstermBackend};
+use std::{
+ io,
+ time::{Duration, Instant},
+};
+
+pub async fn run() -> Result<(), io::Error> {
+ enable_raw_mode()?;
+ let mut stdout = io::stdout();
+ execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
+ let backend = CrosstermBackend::new(stdout);
+ let mut terminal = Terminal::new(backend)?;
+
+ let mut app = App::default();
+ let tick_rate = Duration::from_millis(512);
+ let mut last_tick = Instant::now();
+
+ loop {
+ terminal.draw(|f| ui::render(f, &app))?;
+
+ let timeout = tick_rate
+ .checked_sub(last_tick.elapsed())
+ .unwrap_or(Duration::from_secs(0));
+
+ if event::poll(timeout)?
+ && let Event::Key(key) = event::read()?
+ && key.kind == KeyEventKind::Press
+ {
+ match key.code {
+ KeyCode::Enter => {
+ let command = app.input.trim().to_string();
+
+ match command.as_str() {
+ "exit" => {
+ app.logs.push("Shutting down…".into());
+ app.should_quit = true;
+ }
+ _ => {
+ app.logs.push(format!("Command entered: {}", command));
+ }
+ }
+ app.input.clear();
+ }
+ KeyCode::Char(c) => {
+ app.input.push(c);
+ }
+ KeyCode::Backspace => {
+ app.input.pop();
+ }
+ _ => {}
+ }
+ }
+
+ if last_tick.elapsed() >= tick_rate {
+ app.on_tick();
+ last_tick = Instant::now();
+ }
+
+ if app.should_quit {
+ break;
+ }
+ }
+
+ disable_raw_mode()?;
+
+ execute!(
+ terminal.backend_mut(),
+ LeaveAlternateScreen,
+ DisableMouseCapture
+ )?;
+
+ terminal.show_cursor()?;
+
+ Ok(())
+}
diff --git a/src/cli/ui.rs b/src/cli/ui.rs
new file mode 100644
index 00000000..78f05efb
--- /dev/null
+++ b/src/cli/ui.rs
@@ -0,0 +1,251 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+use ratatui::{
+ Frame,
+ layout::{Constraint, Direction, Layout},
+ style::{Color, Modifier, Style},
+ text::{Line, Span},
+ widgets::{Block, Borders, Paragraph, Row, Sparkline, Table, Wrap},
+};
+
+use crate::cli::App;
+
+pub fn render(f: &mut Frame, app: &App) {
+ let chunks = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints([
+ Constraint::Length(6), // Top row info
+ Constraint::Min(10), // Middle row (Input & Logs)
+ Constraint::Length(10), // Bottom row (Table & Graphs)
+ ])
+ .split(f.area());
+
+ // --- TOP ROW ---
+ let top_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints([
+ Constraint::Percentage(33),
+ Constraint::Percentage(33),
+ Constraint::Percentage(34),
+ ])
+ .split(chunks[0]);
+
+ // Server Info
+ let server_info = vec![
+ Line::from(vec![
+ Span::raw("Connections: "),
+ Span::styled(
+ format!("{}", app.server_connections),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("RPS: "),
+ Span::styled(
+ format!("{:.1}", app.server_rps),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Errors: "),
+ Span::styled(
+ format!("{}", app.server_errors),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Data ↑↓: "),
+ Span::styled(
+ format!("{} B / {} B", app.server_data_up, app.server_data_down),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ ];
+ let server_block = Block::default().borders(Borders::ALL).title("Server");
+ f.render_widget(
+ Paragraph::new(server_info).block(server_block),
+ top_chunks[0],
+ );
+
+ // Pool Info
+ let pool_info = vec![
+ Line::from(vec![
+ Span::raw("Workers(Miners): "),
+ Span::styled(
+ format!("{}", app.pool_workers),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Hashrate(Total): "),
+ Span::styled(
+ format!("{:.2} GH/s", app.pool_hashrate),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Blocks: "),
+ Span::styled(
+ format!("{}", app.pool_blocks),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Shares: "),
+ Span::styled(
+ format!("{} ✓ / {} ✗", app.pool_shares_good, app.pool_shares_bad),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ ];
+ let pool_block = Block::default().borders(Borders::ALL).title("Pool");
+ f.render_widget(Paragraph::new(pool_info).block(pool_block), top_chunks[1]);
+
+ // Users Info
+ let users_info = vec![
+ Line::from(vec![
+ Span::raw("Active: "),
+ Span::styled(
+ format!("{}", app.users_active),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Total: "),
+ Span::styled(
+ format!("{}", app.users_total),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("New Today: "),
+ Span::styled(
+ format!("{}", app.users_new_today),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ Line::from(vec![
+ Span::raw("Verified: "),
+ Span::styled(
+ format!("{}", app.users_verified),
+ Style::default().fg(Color::Yellow),
+ ),
+ ]),
+ ];
+ let users_block = Block::default().borders(Borders::ALL).title("Users");
+ f.render_widget(Paragraph::new(users_info).block(users_block), top_chunks[2]);
+
+ // --- MIDDLE ROW ---
+ let middle_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints([Constraint::Percentage(60), Constraint::Percentage(40)])
+ .split(chunks[1]);
+
+ // CLI Input area
+ let input_text = vec![
+ Line::from(vec![
+ Span::styled("Type ", Style::default().fg(Color::Yellow)),
+ Span::styled("'help'", Style::default().fg(Color::Yellow)),
+ Span::raw(" for commands, "),
+ Span::styled("'exit'", Style::default().fg(Color::Yellow)),
+ Span::raw(" to quit."),
+ ]),
+ Line::from(format!("> {}", app.input)),
+ ];
+
+ let input_block = Block::default()
+ .borders(Borders::ALL)
+ .title("DUCO Server $");
+ f.render_widget(
+ Paragraph::new(input_text).block(input_block),
+ middle_chunks[0],
+ );
+
+ // Logs
+ let log_lines: Vec = app.logs.iter().map(|l| Line::from(l.as_str())).collect();
+ let logs_block = Block::default().borders(Borders::ALL).title("Logs");
+ f.render_widget(
+ Paragraph::new(log_lines)
+ .block(logs_block)
+ .wrap(Wrap { trim: true }),
+ middle_chunks[1],
+ );
+
+ // --- BOTTOM ROW ---
+ let bottom_chunks = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints([
+ Constraint::Percentage(60),
+ Constraint::Percentage(20),
+ Constraint::Percentage(20),
+ ])
+ .split(chunks[2]);
+
+ // Connections Table
+ let rows: Vec = app
+ .connections
+ .iter()
+ .map(|c| {
+ Row::new(vec![
+ c.name.clone(),
+ c.ip.clone(),
+ c.port.to_string(),
+ c.status.clone(),
+ c.sent.clone(),
+ c.received.clone(),
+ c.uptime.clone(),
+ ])
+ })
+ .collect();
+
+ let table = Table::new(
+ rows,
+ [
+ Constraint::Percentage(15),
+ Constraint::Percentage(20),
+ Constraint::Percentage(10),
+ Constraint::Percentage(15),
+ Constraint::Percentage(15),
+ Constraint::Percentage(15),
+ Constraint::Percentage(10),
+ ],
+ )
+ .header(
+ Row::new(vec![
+ "Name", "IP", "Port", "Status", "Sent", "Received", "Uptime",
+ ])
+ .style(Style::default().add_modifier(Modifier::BOLD)),
+ )
+ .block(Block::default().borders(Borders::ALL).title("Connections"));
+ f.render_widget(table, bottom_chunks[0]);
+
+ // CPU Usage
+ let cpu_data: Vec = app.cpu_usage.iter().map(|&v| v as u64).collect();
+ let cpu_sparkline = Sparkline::default()
+ .block(Block::default().borders(Borders::ALL).title(format!(
+ "CPU Usage: {:.1}%",
+ app.cpu_usage.last().unwrap_or(&0.0)
+ )))
+ .data(&cpu_data)
+ .style(Style::default().fg(Color::Red));
+ f.render_widget(cpu_sparkline, bottom_chunks[1]);
+
+ // Memory Usage
+ let mem_data: Vec = app.mem_usage.iter().map(|&v| v as u64).collect();
+ let mem_sparkline = Sparkline::default()
+ .block(Block::default().borders(Borders::ALL).title(format!(
+ "Memory Usage: {:.1}%",
+ app.mem_usage.last().unwrap_or(&0.0)
+ )))
+ .data(&mem_data)
+ .style(Style::default().fg(Color::Yellow));
+ f.render_widget(mem_sparkline, bottom_chunks[2]);
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
new file mode 100644
index 00000000..5146c3e9
--- /dev/null
+++ b/src/config/mod.rs
@@ -0,0 +1,22 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+use crate::types::{Config, ConfigError};
+use std::path::PathBuf;
+
+impl Config {
+ pub fn load_from_file(&mut self, path: &str) -> Result<(), ConfigError> {
+ let config_path = PathBuf::from(path);
+ let config_content = std::fs::read_to_string(config_path)?;
+ let config: Config = toml::from_str(&config_content)?;
+ *self = config;
+ Ok(())
+ }
+}
diff --git a/src/db/create_tables.rs b/src/db/create_tables.rs
new file mode 100644
index 00000000..aab32bab
--- /dev/null
+++ b/src/db/create_tables.rs
@@ -0,0 +1,165 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+pub async fn run() -> Result<(), sqlx::Error> {
+ let pool = crate::db::pool();
+
+ // Transactions
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Transactions (
+ id SERIAL PRIMARY KEY,
+ timestamp TEXT,
+ username TEXT,
+ recipient TEXT,
+ amount REAL,
+ hash TEXT,
+ memo TEXT,
+ ip_addr TEXT
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Cards
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Cards (
+ timestamp REAL,
+ username TEXT,
+ value REAL,
+ key TEXT UNIQUE
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Blocks
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Blocks (
+ timestamp TEXT,
+ finder TEXT,
+ amount REAL,
+ hash TEXT
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Limits
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Limits (
+ username TEXT,
+ exlimit REAL,
+ last REAL
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Users
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Users (
+ username TEXT,
+ password TEXT,
+ email TEXT,
+ balance REAL,
+ created TEXT DEFAULT 'before 23.08.2021',
+ rig_verified TEXT DEFAULT 'No',
+ last_seen INTEGER DEFAULT 0,
+ stake INTEGER DEFAULT 0,
+ warnings INTEGER DEFAULT 0,
+ ban_reason TEXT DEFAULT 'None',
+ ban INTEGER DEFAULT 0,
+ max_miners INTEGER DEFAULT 2,
+ reg_country TEXT DEFAULT 'None',
+ trustscore INTEGER DEFAULT 0,
+ miner_password INTEGER
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Server
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Server (
+ blocks REAL,
+ lastBlockHash TEXT
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Pools
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS Pools (
+ identifier TEXT,
+ name TEXT,
+ url TEXT,
+ cpu REAL,
+ ram REAL,
+ connections INTEGER,
+ lastsync INTEGER,
+ hidden BOOLEAN DEFAULT FALSE
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Alt Accounts
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS alt_accounts (
+ ip_addr TEXT,
+ usernames TEXT,
+ change INTEGER
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Chain Alts
+ sqlx::query(
+ r#"
+ CREATE TABLE IF NOT EXISTS chain_accounts(
+ address TEXT,
+ username TEXT
+ )
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ // Initial block
+ sqlx::query(
+ r#"
+ INSERT INTO Server (blocks, lastBlockHash)
+ SELECT 1, 'ba29a15896fd2d792d5c4b60668bf2b9feebc51d'
+ WHERE NOT EXISTS (SELECT 1 FROM Server)
+ "#,
+ )
+ .execute(pool)
+ .await?;
+
+ Ok(())
+}
diff --git a/src/db/mod.rs b/src/db/mod.rs
new file mode 100644
index 00000000..6fc17216
--- /dev/null
+++ b/src/db/mod.rs
@@ -0,0 +1,44 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+pub mod create_tables;
+
+use sqlx::{Pool, Postgres, postgres::PgPoolOptions};
+use std::sync::OnceLock;
+
+static DB_POOL: OnceLock> = OnceLock::new();
+
+pub async fn connect(
+ host: &str,
+ port: u16,
+ user: &str,
+ password: &str,
+ database: &str,
+) -> Result<(), sqlx::Error> {
+ let url = format!(
+ "postgres://{}:{}@{}:{}/{}",
+ user, password, host, port, database
+ );
+
+ let pool = PgPoolOptions::new()
+ .max_connections(5)
+ .connect(&url)
+ .await?;
+
+ DB_POOL.set(pool).expect("DB already initialized");
+
+ create_tables::run().await?;
+
+ Ok(())
+}
+
+pub fn pool() -> &'static Pool {
+ DB_POOL.get().expect("DB not initialized")
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 00000000..a3089fac
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,14 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+pub mod cli;
+pub mod config;
+pub mod db;
+pub mod types;
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 00000000..b5e87605
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,33 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+use master_server::types::Config;
+
+#[tokio::main]
+async fn main() -> Result<(), Box> {
+ let mut config = Config::default();
+
+ config.load_from_file("config.toml")?;
+
+ // Connect to DB
+ master_server::db::connect(
+ &config.database_ip,
+ config.database_port,
+ &config.database_user,
+ &config.database_password,
+ &config.database_name,
+ )
+ .await?;
+
+ // Start CLI
+ master_server::cli::run().await?;
+
+ Ok(())
+}
diff --git a/src/types/config.rs b/src/types/config.rs
new file mode 100644
index 00000000..dc5e5155
--- /dev/null
+++ b/src/types/config.rs
@@ -0,0 +1,56 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+use serde::{Deserialize, Serialize};
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum ConfigError {
+ #[error("failed to read config file: {0}")]
+ Io(#[from] std::io::Error),
+ #[error("failed to parse config file: {0}")]
+ Toml(#[from] toml::de::Error),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Config {
+ pub host: String,
+ pub ports: Vec,
+ pub database_ip: String,
+ pub database_port: u16,
+ pub database_name: String,
+ pub database_user: String,
+ pub database_password: String,
+}
+
+impl Default for Config {
+ fn default() -> Self {
+ Self {
+ host: "0.0.0.0".to_string(),
+ ports: vec![
+ 2806, // Pools
+ 2807, // Pools
+ 2808, // Pools
+ 2809, // Pools
+ 2810, // Pools
+ 2811, // General purpose
+ 2812, // General purpose
+ 2813, // General purpose
+ 2814, // General purpose
+ 2815, // General purpose
+ ],
+ database_ip: "127.0.0.1".to_string(),
+ database_port: 5432,
+ database_name: "duco".to_string(),
+ database_user: "root".to_string(),
+ database_password: "".to_string(),
+ }
+ }
+}
diff --git a/src/types/mod.rs b/src/types/mod.rs
new file mode 100644
index 00000000..f3cf48f0
--- /dev/null
+++ b/src/types/mod.rs
@@ -0,0 +1,12 @@
+// ===============================================================
+// Duino-Coin Master Server
+//
+// https://duinocoin.com
+//
+// Copyright (c) 2019-2026 Duino-Coin Team & Community
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+// ===============================================================
+
+pub mod config;
+pub use config::*;