Compare commits
6 Commits
3.2.0
..
65b607fb31
| Author | SHA1 | Date | |
|---|---|---|---|
| 65b607fb31 | |||
| 1c6c9a2d6e | |||
| b84ddaf1b7 | |||
| 3baa262ca6 | |||
| c648cfd2b3 | |||
| d50cdd2a77 |
@@ -1,10 +1,2 @@
|
|||||||
.DS_Store
|
node_modules/
|
||||||
node_modules
|
yarn.lock
|
||||||
/build
|
|
||||||
/.svelte-kit
|
|
||||||
/package
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
!.env.example
|
|
||||||
vite.config.js.timestamp-*
|
|
||||||
vite.config.ts.timestamp-*
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# Package Managers
|
|
||||||
package-lock.json
|
|
||||||
pnpm-lock.yaml
|
|
||||||
yarn.lock
|
|
||||||
bun.lock
|
|
||||||
bun.lockb
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
/static/
|
|
||||||
|
|
||||||
# Tauri
|
|
||||||
/src-tauri/
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
"bracketSameLine": false,
|
|
||||||
"insertPragma": false,
|
|
||||||
"arrowParens": "always",
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"printWidth": 100,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false,
|
|
||||||
"bracketSpacing": true,
|
|
||||||
"plugins": ["prettier-plugin-svelte"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "*.svelte",
|
|
||||||
"options": {
|
|
||||||
"parser": "svelte"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files": "*.{css,pcss}",
|
|
||||||
"options": {
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false,
|
|
||||||
"singleQuote": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": [
|
|
||||||
"svelte.svelte-vscode",
|
|
||||||
"tauri-apps.tauri-vscode",
|
|
||||||
"rust-lang.rust-analyzer",
|
|
||||||
"esbenp.prettier-vscode",
|
|
||||||
"fill-labs.dependi",
|
|
||||||
"mylesmurphy.prettify-ts",
|
|
||||||
"edwinhuish.better-comments-next",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"bradlc.vscode-tailwindcss"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"svelte.enable-ts-plugin": true,
|
|
||||||
"git.enableCommitSigning": true,
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
||||||
"[rust]": {
|
|
||||||
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
|
||||||
},
|
|
||||||
"json.schemaDownload.trustedDomains": {
|
|
||||||
"https://schemastore.azurewebsites.net/": true,
|
|
||||||
"https://raw.githubusercontent.com/": true,
|
|
||||||
"https://www.schemastore.org/": true,
|
|
||||||
"https://json.schemastore.org/": true,
|
|
||||||
"https://json-schema.org/": true,
|
|
||||||
"https://schema.tauri.app/": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,673 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
Copyright (C) 2025 HorizonCode
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program 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 General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
EZPPLauncher Copyright (C) 2025 HorizonCode
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
@@ -1,82 +1,23 @@
|
|||||||
# EZPPLauncher
|
# EZPPLauncher
|
||||||
|
|
||||||
**EZPPLauncher** is a custom launcher for the private osu! server [EZPPFarm](https://ez-pp.farm), built with **Rust** and **Svelte** using the [Tauri](https://tauri.app) framework.
|
Welcome to the EZPPLauncher! A new way to connect to the EZPPFarm server.
|
||||||
It enhances the osu! experience with quality-of-life features and integration specifically designed for the EZPPFarm community.
|
|
||||||
|
|
||||||
---
|
Just one click and you are ready to go!
|
||||||
|
|
||||||
## 🖼️ Preview
|
## Installation
|
||||||
|
The Launcher is a "plug and play thing", download it, place it on the desktop and execute!
|
||||||
|
|
||||||

|
## Features
|
||||||
|
|
||||||
---
|
* Automatic osu! client updating before Launch
|
||||||
|
* Account saving (soon)
|
||||||
|
|
||||||
## 🚀 Features
|
## Used Libraries
|
||||||
|
|
||||||
- [x] Automatically updates osu! before launching
|
* [Electron](https://www.npmjs.com/package/electron)
|
||||||
- [x] Automatic ingame login
|
* [custom-electron-titlebar](https://www.npmjs.com/package/custom-electron-titlebar)
|
||||||
- [x] Patches the osu! client to show misses in Relax and Autopilot
|
* [axios](https://www.npmjs.com/package/axios)
|
||||||
- [x] Displays your EZPPFarm stats in the launcher
|
* [jquery](https://www.npmjs.com/package/jquery)
|
||||||
- [x] Shows the number of imported beatmapsets
|
|
||||||
- [x] Shows the number of imported skins
|
|
||||||
- [x] Displays ping to the EZPPFarm server
|
|
||||||
- [x] Discord Rich Presence
|
|
||||||
- [x] Performance Display Overlay (currently in experimental patcher release stream)
|
|
||||||
- [x] Launcher Theming
|
|
||||||
|
|
||||||
---
|
## License
|
||||||
|
[AGPL-3.0](https://choosealicense.com/licenses/agpl-3.0/)
|
||||||
## 💻 Supported Platforms
|
|
||||||
|
|
||||||
| Platform | Status |
|
|
||||||
| -------- | ---------------------------------------- |
|
|
||||||
| Windows | ✅ Supported |
|
|
||||||
| macOS | ❌ Not supported |
|
|
||||||
| Linux | 🕧 Partially supported (via osu-winello) |
|
|
||||||
|
|
||||||
> Currently, only **Windows** is fully supported. Support for other platforms may be considered in the future.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠 Build From Source
|
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
- **Rust** (installed via [rustup](https://rustup.rs/) – recommended for Windows)
|
|
||||||
- **Cargo** (comes with rustup)
|
|
||||||
- **[CMake](https://cmake.org/download/)**
|
|
||||||
- **[Bun](https://bun.sh/)** (JavaScript runtime)
|
|
||||||
|
|
||||||
### Steps
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install all dependencies
|
|
||||||
bun i
|
|
||||||
|
|
||||||
# Build the project
|
|
||||||
bun run build
|
|
||||||
```
|
|
||||||
|
|
||||||
After building, the launcher executable will be located at:
|
|
||||||
|
|
||||||
```
|
|
||||||
src-tauri/target/release/ezpplauncher.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Project Structure (Simplified)
|
|
||||||
|
|
||||||
```
|
|
||||||
├── src/ # Frontend (Svelte)
|
|
||||||
├── src-tauri/ # Backend (Rust)
|
|
||||||
│ ├── tauri.conf.json # Tauri configuration
|
|
||||||
├── package.json # Bun project config
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Launcher Themes
|
|
||||||
|
|
||||||
By default, the launcher includes several downloadable themes. If you want to create your own custom theme, please use the [create-ezpplauncher-theme](https://git.ez-pp.farm/EZPPFarm/create-ezpplauncher-theme) repository for a template and instructions.
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
|
||||||
|
const { setupTitlebar, attachTitlebarToWindow } = require('custom-electron-titlebar/main');
|
||||||
|
const windowManager = require('./ui/windowManager');
|
||||||
|
|
||||||
|
const run = () => {
|
||||||
|
const gotTheLock = app.requestSingleInstanceLock()
|
||||||
|
if (!gotTheLock) {
|
||||||
|
app.quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setupTitlebar();
|
||||||
|
|
||||||
|
let mainWindow;
|
||||||
|
app.whenReady().then(() => {
|
||||||
|
|
||||||
|
mainWindow = createWindow()
|
||||||
|
app.on('activate', function () {
|
||||||
|
if (BrowserWindow.getAllWindows().length === 0) mainWindow = createWindow();
|
||||||
|
})
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
|
ipcMain.handle('open-folder-dialog', async (event) => {
|
||||||
|
const yes = await dialog.showOpenDialog({
|
||||||
|
properties: ['openDirectory']
|
||||||
|
})
|
||||||
|
return yes.filePaths;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWindow() {
|
||||||
|
// Create the browser window.
|
||||||
|
const win = windowManager.createWindow(480, 420);
|
||||||
|
|
||||||
|
win.loadFile('./html/index.html');
|
||||||
|
|
||||||
|
attachTitlebarToWindow(win);
|
||||||
|
win.webContents.setWindowOpenHandler(() => "deny");
|
||||||
|
win.webContents.on('did-finish-load', function () {
|
||||||
|
if (win.webContents.getZoomFactor() != 0.9)
|
||||||
|
win.webContents.setZoomFactor(0.9)
|
||||||
|
});
|
||||||
|
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
@@ -1,911 +0,0 @@
|
|||||||
{
|
|
||||||
"lockfileVersion": 1,
|
|
||||||
"configVersion": 0,
|
|
||||||
"workspaces": {
|
|
||||||
"": {
|
|
||||||
"name": "ezpplauncher",
|
|
||||||
"dependencies": {
|
|
||||||
"@better-fetch/fetch": "^1.1.18",
|
|
||||||
"@fontsource/sora": "^5.2.6",
|
|
||||||
"@fontsource/space-mono": "^5.2.8",
|
|
||||||
"@number-flow/svelte": "^0.4.0",
|
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
|
||||||
"@tauri-apps/api": "^2.10.1",
|
|
||||||
"@tauri-apps/plugin-dialog": "^2.7.0",
|
|
||||||
"@tauri-apps/plugin-fs": "^2.5.0",
|
|
||||||
"@tauri-apps/plugin-shell": "^2.3.5",
|
|
||||||
"animejs": "^4.1.3",
|
|
||||||
"buffer": "^6.0.3",
|
|
||||||
"crypto-js": "^4.2.0",
|
|
||||||
"jszip": "^3.10.1",
|
|
||||||
"lucide-svelte": "^1.0.1",
|
|
||||||
"react": "^19.2.4",
|
|
||||||
"react-dom": "^19.2.4",
|
|
||||||
"react-to-webcomponent": "^2.0.1",
|
|
||||||
"semver": "^7.7.2",
|
|
||||||
"sileo": "^0.1.3",
|
|
||||||
"svelte-confetti": "^2.3.2",
|
|
||||||
"tw-animate-css": "^1.3.8",
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/compat": "^2.0.0",
|
|
||||||
"@eslint/js": "^9.35.0",
|
|
||||||
"@iarna/toml": "2.2.5",
|
|
||||||
"@lucide/svelte": "^1.8.0",
|
|
||||||
"@sveltejs/adapter-static": "^3.0.9",
|
|
||||||
"@sveltejs/kit": "^2.57.1",
|
|
||||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
||||||
"@tauri-apps/cli": "^2.10.0",
|
|
||||||
"@types/bun": "^1.2.21",
|
|
||||||
"@types/crypto-js": "^4.2.2",
|
|
||||||
"@types/react-dom": "^19.2.3",
|
|
||||||
"@types/semver": "^7.7.1",
|
|
||||||
"autoprefixer": "10.4.21",
|
|
||||||
"bits-ui": "^1.4.7",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"eslint": "^9.35.0",
|
|
||||||
"eslint-config-prettier": "^10.1.8",
|
|
||||||
"eslint-plugin-svelte": "^3.12.2",
|
|
||||||
"globals": "^17.0.0",
|
|
||||||
"mode-watcher": "^1.1.0",
|
|
||||||
"prettier": "^3.6.2",
|
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
|
||||||
"sass-embedded": "^1.92.1",
|
|
||||||
"svelte": "^5.55.3",
|
|
||||||
"svelte-check": "^4.3.1",
|
|
||||||
"svelte-sonner": "^1.0.5",
|
|
||||||
"tailwind-merge": "^3.3.1",
|
|
||||||
"tailwind-variants": "^3.1.0",
|
|
||||||
"tailwindcss": "^4.1.7",
|
|
||||||
"tailwindcss-animate": "^1.0.7",
|
|
||||||
"tslib": "^2.8.1",
|
|
||||||
"typescript": "^6.0.2",
|
|
||||||
"typescript-eslint": "^8.42.0",
|
|
||||||
"vite": "^8.0.8",
|
|
||||||
"vite-plugin-devtools-json": "^1.0.0",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"packages": {
|
|
||||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
|
||||||
|
|
||||||
"@better-fetch/fetch": ["@better-fetch/fetch@1.1.18", "", {}, "sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA=="],
|
|
||||||
|
|
||||||
"@bufbuild/protobuf": ["@bufbuild/protobuf@2.5.2", "", {}, "sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg=="],
|
|
||||||
|
|
||||||
"@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="],
|
|
||||||
|
|
||||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
|
|
||||||
|
|
||||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
|
|
||||||
|
|
||||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
|
||||||
|
|
||||||
"@eslint/compat": ["@eslint/compat@2.0.0", "", { "dependencies": { "@eslint/core": "^1.0.0" }, "peerDependencies": { "eslint": "^8.40 || 9" }, "optionalPeers": ["eslint"] }, "sha512-T9AfE1G1uv4wwq94ozgTGio5EUQBqAVe1X9qsQtSNVEYW6j3hvtZVm8Smr4qL1qDPFg+lOB2cL5RxTRMzq4CTA=="],
|
|
||||||
|
|
||||||
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
|
|
||||||
|
|
||||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="],
|
|
||||||
|
|
||||||
"@eslint/core": ["@eslint/core@1.0.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-PRfWP+8FOldvbApr6xL7mNCw4cJcSTq4GA7tYbgq15mRb0kWKO/wEB2jr+uwjFH3sZvEZneZyCUGTxsv4Sahyw=="],
|
|
||||||
|
|
||||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
|
||||||
|
|
||||||
"@eslint/js": ["@eslint/js@9.35.0", "", {}, "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw=="],
|
|
||||||
|
|
||||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
|
||||||
|
|
||||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
|
|
||||||
|
|
||||||
"@floating-ui/core": ["@floating-ui/core@1.7.1", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw=="],
|
|
||||||
|
|
||||||
"@floating-ui/dom": ["@floating-ui/dom@1.7.1", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/utils": "^0.2.9" } }, "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ=="],
|
|
||||||
|
|
||||||
"@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="],
|
|
||||||
|
|
||||||
"@fontsource/sora": ["@fontsource/sora@5.2.6", "", {}, "sha512-OPknOmn82HIJg32UGg9iEjEVFdC+xOZBqrmQNUgsem6hFwBBrqXnTwIpro7leq/uFRdupkN42hc0JJKH20j22w=="],
|
|
||||||
|
|
||||||
"@fontsource/space-mono": ["@fontsource/space-mono@5.2.8", "", {}, "sha512-25X0fg1+kxxLes9/c6AozhrrAuBW1uLaOL584IRg4DZxVxNOMzcS3mHS1UtmsyTwtU2HpiIt9Kv23Q+7xQO+hg=="],
|
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
|
||||||
|
|
||||||
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
|
|
||||||
|
|
||||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
|
||||||
|
|
||||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
|
||||||
|
|
||||||
"@iarna/toml": ["@iarna/toml@2.2.5", "", {}, "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="],
|
|
||||||
|
|
||||||
"@internationalized/date": ["@internationalized/date@3.8.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA=="],
|
|
||||||
|
|
||||||
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
|
||||||
|
|
||||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
|
||||||
|
|
||||||
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
|
||||||
|
|
||||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
|
||||||
|
|
||||||
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
|
||||||
|
|
||||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
|
||||||
|
|
||||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
|
||||||
|
|
||||||
"@lucide/svelte": ["@lucide/svelte@1.8.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-+zYQUKqEOVP5lxbGmxL1OVgGMQtRK91eIJ0bR+3Cr1ts4oQEsQfxyzzd5X47psJlblAuGFrl2xm4YuATjR9oaA=="],
|
|
||||||
|
|
||||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ=="],
|
|
||||||
|
|
||||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
|
||||||
|
|
||||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
|
||||||
|
|
||||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
|
||||||
|
|
||||||
"@number-flow/svelte": ["@number-flow/svelte@0.4.0", "", { "dependencies": { "esm-env": "^1.1.4", "number-flow": "0.6.0" }, "peerDependencies": { "svelte": "^4 || ^5" } }, "sha512-9tnowrlZlBV3IVe3Gm1V7yXSf4Ugag2k7iW45xqb04HXSa1ApEImopvGWAjJpHDvS849o+UCb0YH461Mtde9lA=="],
|
|
||||||
|
|
||||||
"@oxc-project/types": ["@oxc-project/types@0.124.0", "", {}, "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg=="],
|
|
||||||
|
|
||||||
"@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
|
|
||||||
|
|
||||||
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
|
||||||
|
|
||||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
|
||||||
|
|
||||||
"@r2wc/core": ["@r2wc/core@1.3.0", "", {}, "sha512-aPBnND92Itl+SWWbWyyxdFFF0+RqKB6dptGHEdiPB8ZvnHWHlVzOfEvbEcyUYGtB6HBdsfkVuBiaGYyBFVTzVQ=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.15", "", { "os": "android", "cpu": "arm64" }, "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.15", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm" }, "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "ppc64" }, "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "s390x" }, "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.15", "", { "os": "linux", "cpu": "x64" }, "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.15", "", { "os": "none", "cpu": "arm64" }, "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.15", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.3" }, "cpu": "none" }, "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA=="],
|
|
||||||
|
|
||||||
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.15", "", { "os": "win32", "cpu": "x64" }, "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g=="],
|
|
||||||
|
|
||||||
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.15", "", {}, "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g=="],
|
|
||||||
|
|
||||||
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
|
||||||
|
|
||||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
|
||||||
|
|
||||||
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.9", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-aytHXcMi7lb9ljsWUzXYQ0p5X1z9oWud2olu/EpmH7aCu4m84h7QLvb5Wp+CFirKcwoNnYvYWhyP/L8Vh1ztdw=="],
|
|
||||||
|
|
||||||
"@sveltejs/kit": ["@sveltejs/kit@2.57.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.6.4", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": "^5.3.3 || ^6.0.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" }, "optionalPeers": ["@opentelemetry/api", "typescript"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-VRdSbB96cI1EnRh09CqmnQqP/YJvET5buj8S6k7CxaJqBJD4bw4fRKDjcarAj/eX9k2eHifQfDH8NtOh+ZxxPw=="],
|
|
||||||
|
|
||||||
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@7.0.0", "", { "dependencies": { "deepmerge": "^4.3.1", "magic-string": "^0.30.21", "obug": "^2.1.0", "vitefu": "^1.1.2" }, "peerDependencies": { "svelte": "^5.46.4", "vite": "^8.0.0-beta.7 || ^8.0.0" } }, "sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g=="],
|
|
||||||
|
|
||||||
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.11", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.11", "", { "os": "android", "cpu": "arm64" }, "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11", "", { "os": "linux", "cpu": "arm" }, "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.11", "", { "os": "win32", "cpu": "x64" }, "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/typography": ["@tailwindcss/typography@0.5.16", "", { "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.10.0", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.0", "@tauri-apps/cli-darwin-x64": "2.10.0", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.0", "@tauri-apps/cli-linux-arm64-gnu": "2.10.0", "@tauri-apps/cli-linux-arm64-musl": "2.10.0", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-gnu": "2.10.0", "@tauri-apps/cli-linux-x64-musl": "2.10.0", "@tauri-apps/cli-win32-arm64-msvc": "2.10.0", "@tauri-apps/cli-win32-ia32-msvc": "2.10.0", "@tauri-apps/cli-win32-x64-msvc": "2.10.0" }, "bin": { "tauri": "tauri.js" } }, "sha512-ZwT0T+7bw4+DPCSWzmviwq5XbXlM0cNoleDKOYPFYqcZqeKY31KlpoMW/MOON/tOFBPgi31a2v3w9gliqwL2+Q=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-avqHD4HRjrMamE/7R/kzJPcAJnZs0IIS+1nkDP5b+TNBn3py7N2aIo9LIpy+VQq0AkN8G5dDpZtOOBkmWt/zjA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-keDmlvJRStzVFjZTd0xYkBONLtgBC9eMTpmXnBXzsHuawV2q9PvDo2x6D5mhuoMVrJ9QWjgaPKBBCFks4dK71Q=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.0", "", { "os": "linux", "cpu": "arm" }, "sha512-e5u0VfLZsMAC9iHaOEANumgl6lfnJx0Dtjkd8IJpysZ8jp0tJ6wrIkto2OzQgzcYyRCKgX72aKE0PFgZputA8g=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-YrYYk2dfmBs5m+OIMCrb+JH/oo+4FtlpcrTCgiFYc7vcs6m3QDd1TTyWu0u01ewsCtK2kOdluhr/zKku+KP7HA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-GUoPdVJmrJRIXFfW3Rkt+eGK9ygOdyISACZfC/bCSfOnGt8kNdQIQr5WRH9QUaTVFIwxMlQyV3m+yXYP+xhSVA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.0", "", { "os": "linux", "cpu": "none" }, "sha512-JO7s3TlSxshwsoKNCDkyvsx5gw2QAs/Y2GbR5UE2d5kkU138ATKoPOtxn8G1fFT1aDW4LH0rYAAfBpGkDyJJnw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Uvh4SUUp4A6DVRSMWjelww0GnZI3PlVy7VS+DRF5napKuIehVjGl9XD0uKoCoxwAQBLctvipyEK+pDXpJeoHng=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.0", "", { "os": "linux", "cpu": "x64" }, "sha512-AP0KRK6bJuTpQ8kMNWvhIpKUkQJfcPFeba7QshOQZjJ8wOS6emwTN4K5g/d3AbCMo0RRdnZWwu67MlmtJyxC1Q=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-97DXVU3dJystrq7W41IX+82JEorLNY+3+ECYxvXWqkq7DBN6FsA08x/EFGE8N/b0LTOui9X2dvpGGoeZKKV08g=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-EHyQ1iwrWy1CwMalEm9z2a6L5isQ121pe7FcA2xe4VWMJp+GHSDDGvbTv/OPdkt2Lyr7DAZBpZHM6nvlHXEc4A=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NTpyQxkpzGmU6ceWBTY2xRIEaS0ZLbVx1HE1zTA3TY/pV3+cPoPPOs+7YScr4IMzXMtOw7tLw5LEXo5oIG3qaQ=="],
|
|
||||||
|
|
||||||
"@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.7.0", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-4nS/hfGMGCXiAS3LtVjH9AgsSAPJeG/7R+q8agTFqytjnMa4Zq95Bq8WzVDkckpanX+yyRHXnRtrKXkANKDHvw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.5.0", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-c83kbz61AK+rKjhS+je9+stIO27nXj7p9cqeg36TwkIUtxpCFTttlHHtqon6h6FN54cXjyAjlMPOJcW3mwE5XQ=="],
|
|
||||||
|
|
||||||
"@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.5", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-jewtULhiQ7lI7+owCKAjc8tYLJr92U16bPOeAa472LHJdgaibLP83NcfAF2e+wkEcA53FxKQAZ7byDzs2eeizg=="],
|
|
||||||
|
|
||||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.21", "", { "dependencies": { "bun-types": "1.2.21" } }, "sha512-NiDnvEqmbfQ6dmZ3EeUO577s4P5bf4HCTXtI6trMc6f6RzirY5IrF3aIookuSpyslFzrnvv2lmEWv5HyC1X79A=="],
|
|
||||||
|
|
||||||
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
|
||||||
|
|
||||||
"@types/crypto-js": ["@types/crypto-js@4.2.2", "", {}, "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ=="],
|
|
||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
|
||||||
|
|
||||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
|
||||||
|
|
||||||
"@types/node": ["@types/node@20.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA=="],
|
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
|
||||||
|
|
||||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
|
||||||
|
|
||||||
"@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
|
|
||||||
|
|
||||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.42.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/type-utils": "8.42.0", "@typescript-eslint/utils": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.42.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.42.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.42.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.42.0", "@typescript-eslint/types": "^8.42.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0" } }, "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.42.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/utils": "8.42.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.42.0", "", {}, "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.42.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.42.0", "@typescript-eslint/tsconfig-utils": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/visitor-keys": "8.42.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.42.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.42.0", "@typescript-eslint/types": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.42.0", "", { "dependencies": { "@typescript-eslint/types": "8.42.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ=="],
|
|
||||||
|
|
||||||
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
|
||||||
|
|
||||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
|
||||||
|
|
||||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
|
||||||
|
|
||||||
"animejs": ["animejs@4.1.3", "", {}, "sha512-4XzlIsQsku1ycSPzchxxT0N+ohEMZObG71nOSBBkZoV4sgQvtXa/qAANkFpTE6pegdV8JnIBZiB0LfdxNoRNMw=="],
|
|
||||||
|
|
||||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
|
||||||
|
|
||||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
|
||||||
|
|
||||||
"aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="],
|
|
||||||
|
|
||||||
"autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="],
|
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
|
||||||
|
|
||||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
|
||||||
|
|
||||||
"bits-ui": ["bits-ui@1.8.0", "", { "dependencies": { "@floating-ui/core": "^1.6.4", "@floating-ui/dom": "^1.6.7", "@internationalized/date": "^3.5.6", "css.escape": "^1.5.1", "esm-env": "^1.1.2", "runed": "^0.23.2", "svelte-toolbelt": "^0.7.1", "tabbable": "^6.2.0" }, "peerDependencies": { "svelte": "^5.11.0" } }, "sha512-CXD6Orp7l8QevNDcRPLXc/b8iMVgxDWT2LyTwsdLzJKh9CxesOmPuNePSPqAxKoT59FIdU4aFPS1k7eBdbaCxg=="],
|
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
|
||||||
|
|
||||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
|
||||||
|
|
||||||
"browserslist": ["browserslist@4.25.1", "", { "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw=="],
|
|
||||||
|
|
||||||
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
|
|
||||||
|
|
||||||
"buffer-builder": ["buffer-builder@0.2.0", "", {}, "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg=="],
|
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.2.21", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw=="],
|
|
||||||
|
|
||||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001726", "", {}, "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw=="],
|
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
|
||||||
|
|
||||||
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
|
||||||
|
|
||||||
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
|
||||||
|
|
||||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
|
||||||
|
|
||||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
||||||
|
|
||||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
|
||||||
|
|
||||||
"colorjs.io": ["colorjs.io@0.5.2", "", {}, "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw=="],
|
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
|
||||||
|
|
||||||
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
|
||||||
|
|
||||||
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
|
||||||
|
|
||||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
||||||
|
|
||||||
"crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="],
|
|
||||||
|
|
||||||
"css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="],
|
|
||||||
|
|
||||||
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
|
||||||
|
|
||||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
||||||
|
|
||||||
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
|
||||||
|
|
||||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
|
||||||
|
|
||||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
|
||||||
|
|
||||||
"devalue": ["devalue@5.7.1", "", {}, "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA=="],
|
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.176", "", {}, "sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg=="],
|
|
||||||
|
|
||||||
"enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="],
|
|
||||||
|
|
||||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
|
||||||
|
|
||||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
|
||||||
|
|
||||||
"eslint": ["eslint@9.35.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.35.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg=="],
|
|
||||||
|
|
||||||
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
|
|
||||||
|
|
||||||
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.12.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.3.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-NDYltSWcDybvnXD5P3NtrLAfdrgr2lklZsXpyIoSlQfg2d80p/E853XXccu+uVn+w4+Q/iHy4oRw00GJH9I/Cg=="],
|
|
||||||
|
|
||||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
|
||||||
|
|
||||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
|
||||||
|
|
||||||
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
|
||||||
|
|
||||||
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
|
||||||
|
|
||||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
|
||||||
|
|
||||||
"esrap": ["esrap@2.2.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig=="],
|
|
||||||
|
|
||||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
|
||||||
|
|
||||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
|
||||||
|
|
||||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
|
||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
|
||||||
|
|
||||||
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
|
||||||
|
|
||||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
|
||||||
|
|
||||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
|
||||||
|
|
||||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
|
||||||
|
|
||||||
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
|
|
||||||
|
|
||||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
|
||||||
|
|
||||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
|
||||||
|
|
||||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
|
||||||
|
|
||||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
|
||||||
|
|
||||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
|
||||||
|
|
||||||
"fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
|
|
||||||
|
|
||||||
"framer-motion": ["framer-motion@12.34.1", "", { "dependencies": { "motion-dom": "^12.34.1", "motion-utils": "^12.29.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-kcZyNaYQfvE2LlH6+AyOaJAQV4rGp5XbzfhsZpiSZcwDMfZUHhuxLWeyRzf5I7jip3qKRpuimPA9pXXfr111kQ=="],
|
|
||||||
|
|
||||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
|
||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
|
||||||
|
|
||||||
"globals": ["globals@17.0.0", "", {}, "sha512-gv5BeD2EssA793rlFWVPMMCqefTlpusw6/2TbAVMy0FzcG8wKJn4O+NqJ4+XWmmwrayJgw5TzrmWjFgmz1XPqw=="],
|
|
||||||
|
|
||||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
|
||||||
|
|
||||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
|
||||||
|
|
||||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
|
||||||
|
|
||||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
|
||||||
|
|
||||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
|
||||||
|
|
||||||
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
|
||||||
|
|
||||||
"immutable": ["immutable@5.1.3", "", {}, "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg=="],
|
|
||||||
|
|
||||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
|
||||||
|
|
||||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
|
||||||
|
|
||||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
|
||||||
|
|
||||||
"inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="],
|
|
||||||
|
|
||||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
|
||||||
|
|
||||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
|
||||||
|
|
||||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
|
||||||
|
|
||||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
|
||||||
|
|
||||||
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
|
|
||||||
|
|
||||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
|
||||||
|
|
||||||
"jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
|
|
||||||
|
|
||||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
|
||||||
|
|
||||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
|
||||||
|
|
||||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
|
||||||
|
|
||||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
|
||||||
|
|
||||||
"jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
|
|
||||||
|
|
||||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
|
||||||
|
|
||||||
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
|
||||||
|
|
||||||
"known-css-properties": ["known-css-properties@0.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="],
|
|
||||||
|
|
||||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
|
||||||
|
|
||||||
"lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
|
||||||
|
|
||||||
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
|
||||||
|
|
||||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
|
||||||
|
|
||||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
|
||||||
|
|
||||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
|
|
||||||
|
|
||||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
|
|
||||||
|
|
||||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
|
|
||||||
|
|
||||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
|
|
||||||
|
|
||||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
|
|
||||||
|
|
||||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
|
|
||||||
|
|
||||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
|
|
||||||
|
|
||||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
|
|
||||||
|
|
||||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
|
||||||
|
|
||||||
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
|
|
||||||
|
|
||||||
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
|
||||||
|
|
||||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
|
||||||
|
|
||||||
"lodash.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="],
|
|
||||||
|
|
||||||
"lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
|
|
||||||
|
|
||||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
|
||||||
|
|
||||||
"lucide-svelte": ["lucide-svelte@1.0.1", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, "sha512-WvzZgk0pqzgda+AErLvgWxHkfg/+GgUwqKMRHvzt0IqyMdmyEDzDCk3Z+Wo/3y753oIgx8u9Q4eUbWkghFa8Jg=="],
|
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
|
||||||
|
|
||||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
|
||||||
|
|
||||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
|
||||||
|
|
||||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
|
||||||
|
|
||||||
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
|
||||||
|
|
||||||
"minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
|
|
||||||
|
|
||||||
"mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
|
||||||
|
|
||||||
"mode-watcher": ["mode-watcher@1.1.0", "", { "dependencies": { "runed": "^0.25.0", "svelte-toolbelt": "^0.7.1" }, "peerDependencies": { "svelte": "^5.27.0" } }, "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g=="],
|
|
||||||
|
|
||||||
"motion": ["motion@12.34.1", "", { "dependencies": { "framer-motion": "^12.34.1", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-N9RVNGn/NSo85OgHX1wGaUWHvReuQ7dZUwuQRhHyzY2wfVOvY3cEgn0Mw4NXOsXMHL/y7EYuzA+b59PYI6EejA=="],
|
|
||||||
|
|
||||||
"motion-dom": ["motion-dom@12.34.1", "", { "dependencies": { "motion-utils": "^12.29.2" } }, "sha512-SC7ZC5dRcGwku2g7EsPvI4q/EzHumUbqsDNumBmZTLFg+goBO5LTJvDu9MAxx+0mtX4IA78B2be/A3aRjY0jnw=="],
|
|
||||||
|
|
||||||
"motion-utils": ["motion-utils@12.29.2", "", {}, "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A=="],
|
|
||||||
|
|
||||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
|
||||||
|
|
||||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
|
||||||
|
|
||||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
|
||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
|
||||||
|
|
||||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
|
||||||
|
|
||||||
"node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
|
|
||||||
|
|
||||||
"normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
|
|
||||||
|
|
||||||
"number-flow": ["number-flow@0.6.0", "", { "dependencies": { "esm-env": "^1.1.4" } }, "sha512-K8flNq2Wqus53vjp/btVo3qXFkagF8dIdYavreBfE7hlvFFG/b1HMGEH6nZL+mlrJ+4lbLP9OmPv3t2rmRkpSQ=="],
|
|
||||||
|
|
||||||
"obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
|
|
||||||
|
|
||||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
|
||||||
|
|
||||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
|
||||||
|
|
||||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
|
||||||
|
|
||||||
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
|
||||||
|
|
||||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
|
||||||
|
|
||||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
|
||||||
|
|
||||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
|
||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
|
||||||
|
|
||||||
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
|
|
||||||
|
|
||||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
|
||||||
|
|
||||||
"postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
|
|
||||||
|
|
||||||
"postcss-safe-parser": ["postcss-safe-parser@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A=="],
|
|
||||||
|
|
||||||
"postcss-scss": ["postcss-scss@4.0.9", "", { "peerDependencies": { "postcss": "^8.4.29" } }, "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A=="],
|
|
||||||
|
|
||||||
"postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
|
|
||||||
|
|
||||||
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
|
||||||
|
|
||||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
|
||||||
|
|
||||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
|
||||||
|
|
||||||
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.4.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ=="],
|
|
||||||
|
|
||||||
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
|
||||||
|
|
||||||
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
|
||||||
|
|
||||||
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
|
||||||
|
|
||||||
"react-to-webcomponent": ["react-to-webcomponent@2.0.1", "", { "dependencies": { "@r2wc/core": "^1.0.0" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-jpVztcA0SbV6TnBRV6EFuU+hmuuSIxgEww3wRcbneT0ytqn57y9ygeRfUmhzz8+bYg53u1h4COKk8iAextHE+Q=="],
|
|
||||||
|
|
||||||
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
|
||||||
|
|
||||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
|
||||||
|
|
||||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
|
||||||
|
|
||||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
|
||||||
|
|
||||||
"rolldown": ["rolldown@1.0.0-rc.15", "", { "dependencies": { "@oxc-project/types": "=0.124.0", "@rolldown/pluginutils": "1.0.0-rc.15" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", "@rolldown/binding-darwin-x64": "1.0.0-rc.15", "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g=="],
|
|
||||||
|
|
||||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
|
||||||
|
|
||||||
"runed": ["runed@0.23.4", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA=="],
|
|
||||||
|
|
||||||
"rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
|
|
||||||
|
|
||||||
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
|
||||||
|
|
||||||
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
|
||||||
|
|
||||||
"sass": ["sass@1.92.1", "", { "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "optionalDependencies": { "@parcel/watcher": "^2.4.1" }, "bin": { "sass": "sass.js" } }, "sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ=="],
|
|
||||||
|
|
||||||
"sass-embedded": ["sass-embedded@1.92.1", "", { "dependencies": { "@bufbuild/protobuf": "^2.5.0", "buffer-builder": "^0.2.0", "colorjs.io": "^0.5.0", "immutable": "^5.0.2", "rxjs": "^7.4.0", "supports-color": "^8.1.1", "sync-child-process": "^1.0.2", "varint": "^6.0.0" }, "optionalDependencies": { "sass-embedded-all-unknown": "1.92.1", "sass-embedded-android-arm": "1.92.1", "sass-embedded-android-arm64": "1.92.1", "sass-embedded-android-riscv64": "1.92.1", "sass-embedded-android-x64": "1.92.1", "sass-embedded-darwin-arm64": "1.92.1", "sass-embedded-darwin-x64": "1.92.1", "sass-embedded-linux-arm": "1.92.1", "sass-embedded-linux-arm64": "1.92.1", "sass-embedded-linux-musl-arm": "1.92.1", "sass-embedded-linux-musl-arm64": "1.92.1", "sass-embedded-linux-musl-riscv64": "1.92.1", "sass-embedded-linux-musl-x64": "1.92.1", "sass-embedded-linux-riscv64": "1.92.1", "sass-embedded-linux-x64": "1.92.1", "sass-embedded-unknown-all": "1.92.1", "sass-embedded-win32-arm64": "1.92.1", "sass-embedded-win32-x64": "1.92.1" }, "bin": { "sass": "dist/bin/sass.js" } }, "sha512-28YwLnF5atAhogt3E4hXzz/NB9dwKffyw08a7DEasLh94P7+aELkG3ENSHYCWB9QFN14hYNLfwr9ozUsPDhcDQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-all-unknown": ["sass-embedded-all-unknown@1.92.1", "", { "dependencies": { "sass": "1.92.1" }, "cpu": [ "!arm", "!x64", "!arm64", ] }, "sha512-5t6/YZf+vhO3OY/49h8RCL6Cwo78luva0M+TnTM9gu9ASffRXAuOVLNKciSXa3loptyemDDS6IU5/dVH5w0KmA=="],
|
|
||||||
|
|
||||||
"sass-embedded-android-arm": ["sass-embedded-android-arm@1.92.1", "", { "os": "android", "cpu": "arm" }, "sha512-4EjpVVzuksERdgAd4BqeSXFnWtWN3DSRyEIUPJ7BhcS9sfDh2Gf6miI2kNTvIQLJ2XIJynDDcEQ8a1U9KwKUTQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-android-arm64": ["sass-embedded-android-arm64@1.92.1", "", { "os": "android", "cpu": "arm64" }, "sha512-Q+UruGb7yKawHagVmVDRRKsnc4mJZvWMBnuRCu2coJo2FofyqBmXohVGXbxko97sYceA9TJTrUEx3WVKQUNCbQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-android-riscv64": ["sass-embedded-android-riscv64@1.92.1", "", { "os": "android", "cpu": "none" }, "sha512-nCY5btLlX7W7Jc6cCL6D2Yklpiu540EJ2G08YVGu12DrAMCBzqM347CSRf2ojp1H8jyhvmLkaFwnrJWzh+6S+w=="],
|
|
||||||
|
|
||||||
"sass-embedded-android-x64": ["sass-embedded-android-x64@1.92.1", "", { "os": "android", "cpu": "x64" }, "sha512-qYWR3bftJ77aLYwYDFuzDI4dcwVVixxqQxlIQWNGkHRCexj614qGSSHemr18C2eVj3mjXAQxTQxU68U7pkGPAA=="],
|
|
||||||
|
|
||||||
"sass-embedded-darwin-arm64": ["sass-embedded-darwin-arm64@1.92.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-g2yQ3txjMYLKMjL2cW1xRO9nnV3ijf95NbX/QShtV6tiVUETZNWDsRMDEwBNGYY6PTE/UZerjJL1R/2xpQg6WA=="],
|
|
||||||
|
|
||||||
"sass-embedded-darwin-x64": ["sass-embedded-darwin-x64@1.92.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-eH+fgxLQhTEPjZPCgPAVuX5e514Qp/4DMAUMtlNShv4cr4TD5qOp1XlsPYR/b7uE7p2cKFkUpUn/bHNqJ2ay4A=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-arm": ["sass-embedded-linux-arm@1.92.1", "", { "os": "linux", "cpu": "arm" }, "sha512-cT3w8yoQTqrtZvWLJeutEGmawITDTY4J6oSVQjeDcPnnoPt0gOFxem8YMznraACXvahw/2+KJDH33BTNgiPo0A=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-arm64": ["sass-embedded-linux-arm64@1.92.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-dNmlpGeZkry1BofhAdGFBXrpM69y9LlYuNnncf+HfsOOUtj8j0q1RwS+zb5asknhKFUOAG8GCGRY1df7Rwu35g=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-musl-arm": ["sass-embedded-linux-musl-arm@1.92.1", "", { "os": "linux", "cpu": "arm" }, "sha512-nPBos6lI31ef2zQhqTZhFOU7ar4impJbLIax0XsqS269YsiCwjhk11VmUloJTpFlJuKMiVXNo7dPx+katxhD/Q=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-musl-arm64": ["sass-embedded-linux-musl-arm64@1.92.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-TfiEBkCyNzVoOhjHXUT+vZ6+p0ueDbvRw6f4jHdkvljZzXdXMby4wh7BU1odl69rgRTkSvYKhgbErRLDR/F7pQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-musl-riscv64": ["sass-embedded-linux-musl-riscv64@1.92.1", "", { "os": "linux", "cpu": "none" }, "sha512-R+RcJA4EYpJDE9JM1GgPYgZo7x94FlxZ6jPodOQkEaZ1S9kvXVCuP5X/0PXRPhu08KJOfeMsAElzfdAjUf7KJg=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-musl-x64": ["sass-embedded-linux-musl-x64@1.92.1", "", { "os": "linux", "cpu": "x64" }, "sha512-/HolYRGXJjx8nLw6oj5ZrkR7PFM7X/5kE4MYZaFMpDIPIcw3bqB2fUXLo/MYlRLsw7gBAT6hJAMBrNdKuTphfw=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-riscv64": ["sass-embedded-linux-riscv64@1.92.1", "", { "os": "linux", "cpu": "none" }, "sha512-b9bxe0CMsbSsLx3nrR0cq8xpIkoAC6X36o4DGMITF3m2v3KsojC7ru9X0Gz+zUFr6rwpq/0lTNzFLNu6sPNo3w=="],
|
|
||||||
|
|
||||||
"sass-embedded-linux-x64": ["sass-embedded-linux-x64@1.92.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xuiK5Jp5NldW4bvlC7AuX1Wf7o0gLZ3md/hNg+bkTvxtCDgnUHtfdo8Q+xWP11bD9QX31xXFWpmUB8UDLi6XQQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-unknown-all": ["sass-embedded-unknown-all@1.92.1", "", { "dependencies": { "sass": "1.92.1" }, "os": [ "!linux", "!win32", "!darwin", "!android", ] }, "sha512-AT9oXvtNY4N+Nd0wvoWqq9A5HjdH/X3aUH4boQUtXyaJ/9DUwnQmBpP5Gtn028ZS8exOGBdobmmWAuigv0k/OA=="],
|
|
||||||
|
|
||||||
"sass-embedded-win32-arm64": ["sass-embedded-win32-arm64@1.92.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-KvmpQjY9yTBMtTYz4WBqetlv9bGaDW1aStcu7MSTbH7YiSybX/9fnxlCAEQv1WlIidQhcJAiyk0Eae+LGK7cIQ=="],
|
|
||||||
|
|
||||||
"sass-embedded-win32-x64": ["sass-embedded-win32-x64@1.92.1", "", { "os": "win32", "cpu": "x64" }, "sha512-B6Nz/GbH7Vkpb2TkQHsGcczWM5t+70VWopWF1x5V5yxLpA8ZzVQ7NTKKi+jDoVY2Efu6ZyzgT9n5KgG2kWliXA=="],
|
|
||||||
|
|
||||||
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
|
||||||
|
|
||||||
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
|
||||||
|
|
||||||
"set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="],
|
|
||||||
|
|
||||||
"setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="],
|
|
||||||
|
|
||||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
|
||||||
|
|
||||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
|
||||||
|
|
||||||
"sileo": ["sileo@0.1.3", "", { "dependencies": { "motion": "^12.34.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-kmGjM2ts2TpuPzOaD7llxcMpU37Pyj5dO8s4wGXvDlR143zV2sB6sJ76PCVP4kY2+hfkrLJhiSm/wXGdUHDFjQ=="],
|
|
||||||
|
|
||||||
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
|
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
|
||||||
|
|
||||||
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
|
||||||
|
|
||||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
|
||||||
|
|
||||||
"style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="],
|
|
||||||
|
|
||||||
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
|
|
||||||
|
|
||||||
"svelte": ["svelte@5.55.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-dS1N+i3bA1v+c4UDb750MlN5vCO82G6vxh8HeTsPsTdJ1BLsN1zxSyDlIdBBqUjqZ/BxEwM8UrFf98aaoVnZFQ=="],
|
|
||||||
|
|
||||||
"svelte-check": ["svelte-check@4.3.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg=="],
|
|
||||||
|
|
||||||
"svelte-confetti": ["svelte-confetti@2.3.2", "", { "peerDependencies": { "svelte": ">=5.0.0" } }, "sha512-cfIwoGqMPYWRYDUz2g7mG1uHYWy7VBepelQdzCC3j/M42UrAqaBYmIi9xaoQfow4fbINHO9WuARnTyK2bjjGQg=="],
|
|
||||||
|
|
||||||
"svelte-eslint-parser": ["svelte-eslint-parser@1.3.1", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-0Iztj5vcOVOVkhy1pbo5uA9r+d3yaVoE5XPc9eABIWDOSJZ2mOsZ4D+t45rphWCOr0uMw3jtSG2fh2e7GvKnPg=="],
|
|
||||||
|
|
||||||
"svelte-sonner": ["svelte-sonner@1.0.5", "", { "dependencies": { "runed": "^0.28.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-9dpGPFqKb/QWudYqGnEz93vuY+NgCEvyNvxoCLMVGw6sDN/3oVeKV1xiEirW2E1N3vJEyj5imSBNOGltQHA7mg=="],
|
|
||||||
|
|
||||||
"svelte-toolbelt": ["svelte-toolbelt@0.7.1", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.23.2", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ=="],
|
|
||||||
|
|
||||||
"sync-child-process": ["sync-child-process@1.0.2", "", { "dependencies": { "sync-message-port": "^1.0.0" } }, "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA=="],
|
|
||||||
|
|
||||||
"sync-message-port": ["sync-message-port@1.1.3", "", {}, "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg=="],
|
|
||||||
|
|
||||||
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
|
|
||||||
|
|
||||||
"tailwind-merge": ["tailwind-merge@3.3.1", "", {}, "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g=="],
|
|
||||||
|
|
||||||
"tailwind-variants": ["tailwind-variants@3.1.0", "", { "peerDependencies": { "tailwind-merge": ">=3.0.0", "tailwindcss": "*" }, "optionalPeers": ["tailwind-merge"] }, "sha512-ieiYaEfUr+sNhw/k++dosmZfVA4VIG5bV+G1eGdJSC4FcflqQv0iSIlOLj/RbzRuTu/VrIiNSlwh1esBM3BXUg=="],
|
|
||||||
|
|
||||||
"tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
|
|
||||||
|
|
||||||
"tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
|
|
||||||
|
|
||||||
"tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
|
|
||||||
|
|
||||||
"tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
|
||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
|
||||||
|
|
||||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
|
||||||
|
|
||||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
|
||||||
|
|
||||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
|
||||||
|
|
||||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
||||||
|
|
||||||
"tw-animate-css": ["tw-animate-css@1.3.8", "", {}, "sha512-Qrk3PZ7l7wUcGYhwZloqfkWCmaXZAoqjkdbIDvzfGshwGtexa/DAs9koXxIkrpEasyevandomzCBAV1Yyop5rw=="],
|
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
|
||||||
|
|
||||||
"typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="],
|
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.42.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.42.0", "@typescript-eslint/parser": "8.42.0", "@typescript-eslint/typescript-estree": "8.42.0", "@typescript-eslint/utils": "8.42.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg=="],
|
|
||||||
|
|
||||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
|
||||||
|
|
||||||
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
|
|
||||||
|
|
||||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
|
||||||
|
|
||||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
|
||||||
|
|
||||||
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
|
||||||
|
|
||||||
"varint": ["varint@6.0.0", "", {}, "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="],
|
|
||||||
|
|
||||||
"vite": ["vite@8.0.8", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw=="],
|
|
||||||
|
|
||||||
"vite-plugin-devtools-json": ["vite-plugin-devtools-json@1.0.0", "", { "dependencies": { "uuid": "^11.1.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-MobvwqX76Vqt/O4AbnNMNWoXWGrKUqZbphCUle/J2KXH82yKQiunOeKnz/nqEPosPsoWWPP9FtNuPBSYpiiwkw=="],
|
|
||||||
|
|
||||||
"vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
|
|
||||||
|
|
||||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
|
||||||
|
|
||||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
|
||||||
|
|
||||||
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
|
||||||
|
|
||||||
"yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
|
|
||||||
|
|
||||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
|
||||||
|
|
||||||
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
|
||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
|
||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
|
||||||
|
|
||||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
|
|
||||||
|
|
||||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
|
||||||
|
|
||||||
"@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" }, "bundled": true }, "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
|
||||||
|
|
||||||
"chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
|
||||||
|
|
||||||
"eslint/@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
|
|
||||||
|
|
||||||
"eslint-plugin-svelte/@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
|
||||||
|
|
||||||
"eslint-plugin-svelte/globals": ["globals@16.3.0", "", {}, "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ=="],
|
|
||||||
|
|
||||||
"esrap/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
|
||||||
|
|
||||||
"magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
|
||||||
|
|
||||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
|
||||||
|
|
||||||
"mode-watcher/runed": ["runed@0.25.0", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg=="],
|
|
||||||
|
|
||||||
"svelte/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
|
||||||
|
|
||||||
"svelte-eslint-parser/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
|
|
||||||
|
|
||||||
"svelte-sonner/runed": ["runed@0.28.0", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ=="],
|
|
||||||
|
|
||||||
"tinyglobby/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
|
||||||
|
|
||||||
"tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
|
||||||
|
|
||||||
"vite/postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
|
|
||||||
|
|
||||||
"@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
|
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
|
||||||
|
|
||||||
"eslint-plugin-svelte/@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://next.shadcn-svelte.com/schema.json",
|
|
||||||
"tailwind": {
|
|
||||||
"css": "src\\app.css",
|
|
||||||
"baseColor": "gray"
|
|
||||||
},
|
|
||||||
"aliases": {
|
|
||||||
"components": "$lib/components",
|
|
||||||
"utils": "$lib/utils",
|
|
||||||
"ui": "$lib/components/ui",
|
|
||||||
"hooks": "$lib/hooks",
|
|
||||||
"lib": "$lib"
|
|
||||||
},
|
|
||||||
"typescript": true,
|
|
||||||
"registry": "https://tw3.shadcn-svelte.com/registry/default"
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import prettier from 'eslint-config-prettier';
|
|
||||||
import { includeIgnoreFile } from '@eslint/compat';
|
|
||||||
import js from '@eslint/js';
|
|
||||||
import svelte from 'eslint-plugin-svelte';
|
|
||||||
import globals from 'globals';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import ts from 'typescript-eslint';
|
|
||||||
import svelteConfig from './svelte.config.js';
|
|
||||||
|
|
||||||
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
|
|
||||||
|
|
||||||
export default ts.config(
|
|
||||||
includeIgnoreFile(gitignorePath),
|
|
||||||
js.configs.recommended,
|
|
||||||
...ts.configs.recommended,
|
|
||||||
...svelte.configs.recommended,
|
|
||||||
prettier,
|
|
||||||
...svelte.configs.prettier,
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
globals: { ...globals.browser, ...globals.node },
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
|
|
||||||
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
|
|
||||||
'no-undef': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
|
|
||||||
languageOptions: {
|
|
||||||
parserOptions: {
|
|
||||||
projectService: true,
|
|
||||||
extraFileExtensions: ['.svelte'],
|
|
||||||
parser: ts.parser,
|
|
||||||
svelteConfig,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
rules: {
|
|
||||||
'no-empty': 'off',
|
|
||||||
'@typescript-eslint/no-unused-vars': [
|
|
||||||
'error',
|
|
||||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^\\$\\$(Props|Events|Slots|Generic)$' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>EZPPLauncher</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link href="../assets/mdb.min.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="fixed-sn mdb-skin-custom" data-spy="scroll" data-target="#scrollspy" data-offset="15"
|
||||||
|
oncontextmenu="return false;">
|
||||||
|
<main style="margin-top: 2rem;">
|
||||||
|
<div class="noselect">
|
||||||
|
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center text-lg-end d-flex align-items-center justify-content-center"
|
||||||
|
style="border-radius: 0.5em;">
|
||||||
|
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3">
|
||||||
|
<div class="container py-2 h-100">
|
||||||
|
<div class="row d-flex justify-content-center align-items-center h-100">
|
||||||
|
<div class="col col-xl-10">
|
||||||
|
<div class="card" style="border-radius: 1rem;">
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="card-body p-4 p-lg-5 text-black">
|
||||||
|
<div class="d-flex align-items-center mb-3 pb-1 text-white">
|
||||||
|
<span class="h1 fw-bold mb-0">EZPPLauncher</span>
|
||||||
|
</div>
|
||||||
|
<h5 class="fw-normal mb-3 pb-3 text-white text-start"
|
||||||
|
style="letter-spacing: 1px;">
|
||||||
|
Launch osu! with connection to the EZPPFarm server
|
||||||
|
</h5>
|
||||||
|
<div class="pt-1 mb-4">
|
||||||
|
<button id="launch-btn" class="btn btn-primary btn-lg btn-block"
|
||||||
|
type="button" style="background-color:#d6016f" disabled>Launch</button>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-dark btn-sm float-start" id="folder-btn">
|
||||||
|
set osu! directory
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
<script type="text/javascript" src="../assets/mdb.min.js"></script>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -1,81 +1,51 @@
|
|||||||
{
|
{
|
||||||
"name": "ezpplauncher",
|
"name": "ezpplauncher",
|
||||||
"version": "3.2.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"main": "app.js",
|
||||||
"type": "module",
|
"license": "MIT",
|
||||||
"scripts": {
|
"build": {
|
||||||
"debug": "bun run tauri dev",
|
"appId": "farm.ezpp.ezppfarm.launcher",
|
||||||
"build": "bun ./scripts/sync-version.ts && bun run vite:build && bun run tauri:build",
|
"productName": "ezpplauncher",
|
||||||
"vite:dev": "vite dev",
|
"directories": {
|
||||||
"vite:build": "vite build",
|
"output": "release",
|
||||||
"tauri:build": "tauri build",
|
"buildResources": "dist"
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
||||||
"tauri": "tauri",
|
|
||||||
"tauri:update-logo": "bun run tauri icon ./static/logo.png",
|
|
||||||
"format": "prettier --write .",
|
|
||||||
"lint": "prettier --check . && eslint ."
|
|
||||||
},
|
},
|
||||||
"license": "GPL-3.0-only",
|
"asar": true,
|
||||||
"dependencies": {
|
"win": {
|
||||||
"@better-fetch/fetch": "^1.1.18",
|
"icon": "./assets/logo.png",
|
||||||
"@fontsource/sora": "^5.2.6",
|
"target": [
|
||||||
"@fontsource/space-mono": "^5.2.8",
|
"portable"
|
||||||
"@number-flow/svelte": "^0.4.0",
|
]
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
},
|
||||||
"@tailwindcss/vite": "^4.1.11",
|
"nsis": {
|
||||||
"@tauri-apps/api": "^2.10.1",
|
"runAfterFinish": true
|
||||||
"@tauri-apps/plugin-dialog": "^2.7.0",
|
},
|
||||||
"@tauri-apps/plugin-fs": "^2.5.0",
|
"portable": {
|
||||||
"@tauri-apps/plugin-shell": "^2.3.5",
|
"artifactName": "EZPPLauncher.exe"
|
||||||
"animejs": "^4.1.3",
|
}
|
||||||
"buffer": "^6.0.3",
|
},
|
||||||
"crypto-js": "^4.2.0",
|
"frontend": {
|
||||||
"jszip": "^3.10.1",
|
"config": {
|
||||||
"lucide-svelte": "^1.0.1",
|
"applicationName": "EZPPLauncher"
|
||||||
"react": "^19.2.4",
|
}
|
||||||
"react-dom": "^19.2.4",
|
},
|
||||||
"react-to-webcomponent": "^2.0.1",
|
"scripts": {
|
||||||
"semver": "^7.7.2",
|
"start": "electron .",
|
||||||
"sileo": "^0.1.3",
|
"pack-win": "electron-builder --x64",
|
||||||
"svelte-confetti": "^2.3.2",
|
"pack-win32": "electron-builder --ia32",
|
||||||
"tw-animate-css": "^1.3.8"
|
"pack-winarm": "electron-builder --arm64",
|
||||||
|
"pack-linux": "electron-builder --dir --linux --ia32 --arm64 --x64",
|
||||||
|
"pack-mac": "electron-builder --dir --mac --ia32 --arm64 --x64",
|
||||||
|
"dist": "electron-builder"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^2.0.0",
|
"electron": "^17.4.3",
|
||||||
"@eslint/js": "^9.35.0",
|
"electron-builder": "^23.0.3",
|
||||||
"@iarna/toml": "2.2.5",
|
"electron-packager": "^15.5.1"
|
||||||
"@lucide/svelte": "^1.8.0",
|
},
|
||||||
"@sveltejs/adapter-static": "^3.0.9",
|
"dependencies": {
|
||||||
"@sveltejs/kit": "^2.57.1",
|
"axios": "^0.27.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
"custom-electron-titlebar": "^4.1.1",
|
||||||
"@tauri-apps/cli": "^2.10.0",
|
"jquery": "^3.6.0"
|
||||||
"@types/bun": "^1.2.21",
|
|
||||||
"@types/crypto-js": "^4.2.2",
|
|
||||||
"@types/react-dom": "^19.2.3",
|
|
||||||
"@types/semver": "^7.7.1",
|
|
||||||
"autoprefixer": "10.4.21",
|
|
||||||
"bits-ui": "^1.4.7",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"eslint": "^9.35.0",
|
|
||||||
"eslint-config-prettier": "^10.1.8",
|
|
||||||
"eslint-plugin-svelte": "^3.12.2",
|
|
||||||
"globals": "^17.0.0",
|
|
||||||
"mode-watcher": "^1.1.0",
|
|
||||||
"prettier": "^3.6.2",
|
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
|
||||||
"sass-embedded": "^1.92.1",
|
|
||||||
"svelte": "^5.55.3",
|
|
||||||
"svelte-check": "^4.3.1",
|
|
||||||
"svelte-sonner": "^1.0.5",
|
|
||||||
"tailwind-merge": "^3.3.1",
|
|
||||||
"tailwind-variants": "^3.1.0",
|
|
||||||
"tailwindcss": "^4.1.7",
|
|
||||||
"tailwindcss-animate": "^1.0.7",
|
|
||||||
"tslib": "^2.8.1",
|
|
||||||
"typescript": "^6.0.2",
|
|
||||||
"typescript-eslint": "^8.42.0",
|
|
||||||
"vite": "^8.0.8",
|
|
||||||
"vite-plugin-devtools-json": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
const { Titlebar, Color } = require('custom-electron-titlebar');
|
||||||
|
let titlebar;
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
titlebar = new Titlebar({
|
||||||
|
backgroundColor: Color.fromHex("#303030"),
|
||||||
|
itemBackgroundColor: Color.fromHex("#121212"),
|
||||||
|
icon: "https://ez-pp.farm/static/logos/circle.png",
|
||||||
|
menu: null,
|
||||||
|
maximizable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
titlebar.updateTitle("EZPPLauncher");
|
||||||
|
|
||||||
|
const $ = require('jquery');
|
||||||
|
|
||||||
|
$("#folder-btn").on('click', async () => {
|
||||||
|
const folderLoc = await ipcRenderer.invoke('open-folder-dialog');
|
||||||
|
alert(folderLoc);
|
||||||
|
});
|
||||||
|
})
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import * as toml from '@iarna/toml';
|
|
||||||
import { cwd } from 'process';
|
|
||||||
|
|
||||||
const packageJsonPath = path.join(cwd(), 'package.json');
|
|
||||||
const cargoTomlPath = path.join(cwd(), 'src-tauri', 'Cargo.toml');
|
|
||||||
const tauriConfPath = path.join(cwd(), 'src-tauri', 'tauri.conf.json');
|
|
||||||
|
|
||||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
||||||
const version = packageJson.version;
|
|
||||||
if (!version) throw new Error('Could not find version in package.json');
|
|
||||||
|
|
||||||
let cargoTomlContent = fs.readFileSync(cargoTomlPath, 'utf8');
|
|
||||||
const cargo = toml.parse(cargoTomlContent) as { package: { version: string } };
|
|
||||||
|
|
||||||
if (cargo.package.version !== version) {
|
|
||||||
cargoTomlContent = cargoTomlContent.replace(/version = ".*?"/, `version = "${version}"`);
|
|
||||||
fs.writeFileSync(cargoTomlPath, cargoTomlContent);
|
|
||||||
console.log(`✅ Synced Cargo.toml version to ${version}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tauriConf = JSON.parse(fs.readFileSync(tauriConfPath, 'utf8'));
|
|
||||||
if (tauriConf.version !== version) {
|
|
||||||
tauriConf.version = version;
|
|
||||||
fs.writeFileSync(tauriConfPath, JSON.stringify(tauriConf, null, 2));
|
|
||||||
console.log(`✅ Synced tauri.conf.json version to ${version}`);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
|
|
||||||
# Generated by Tauri
|
|
||||||
# will have schema files for capabilities auto-completion
|
|
||||||
/gen/schemas
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "ezpplauncher"
|
|
||||||
version = "3.2.0"
|
|
||||||
description = "EZPPLauncher redefined."
|
|
||||||
authors = ["HorizonCode"]
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
incremental = true # Compile your binary in smaller steps.
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
codegen-units = 1 # Allows LLVM to perform better optimization.
|
|
||||||
lto = true # Enables link-time-optimizations.
|
|
||||||
opt-level = "s" # Prioritizes small binary size. Use `3` if you prefer speed.
|
|
||||||
panic = "abort" # Higher performance by disabling panic handlers.
|
|
||||||
strip = true # Ensures debug symbols are removed.
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
# The `_lib` suffix may seem redundant but it is necessary
|
|
||||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
|
||||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
|
||||||
name = "ezpplauncher_lib"
|
|
||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
tauri-build = { version = "2.5.6", features = [] }
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tauri = { version = "2.10.3", features = ["protocol-asset"] }
|
|
||||||
tauri-plugin-shell = "2.3.5"
|
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
|
||||||
serde_json = "1.0.149"
|
|
||||||
serde_repr = "0.1.20"
|
|
||||||
tauri-plugin-dialog = "2.7.0"
|
|
||||||
tauri-plugin-fs = "2.5.0"
|
|
||||||
hardware-id = "0.3.0"
|
|
||||||
tauri-plugin-cors-fetch = "5.0.0"
|
|
||||||
sysinfo = "0.38.4"
|
|
||||||
reqwest = { version = "0.13.2", features = ["json", "stream", "query"] }
|
|
||||||
md5 = "0.8.0"
|
|
||||||
tokio = { version = "1.52.1", features = ["full"] }
|
|
||||||
open = "5.3.4"
|
|
||||||
discord-rich-presence = "1.1.0"
|
|
||||||
once_cell = "1.21.4"
|
|
||||||
futures-util = "0.3.32"
|
|
||||||
byteorder = "1.5.0"
|
|
||||||
anyhow = "1.0.102"
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
|
||||||
winreg = "0.56.0"
|
|
||||||
winapi = { version = "0.3", features = ["winuser", "wincrypt", "memoryapi", "winbase", "dpapi"] }
|
|
||||||
base64 = "0.22.1"
|
|
||||||
widestring = "1.2.1"
|
|
||||||
windows-sys = "0.61.2"
|
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
|
||||||
tauri-plugin-single-instance = "2.4.1"
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
tauri_build::build()
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../gen/schemas/desktop-schema.json",
|
|
||||||
"identifier": "default",
|
|
||||||
"description": "Capability for the main window",
|
|
||||||
"windows": [
|
|
||||||
"main"
|
|
||||||
],
|
|
||||||
"permissions": [
|
|
||||||
"core:default",
|
|
||||||
"shell:allow-open",
|
|
||||||
"shell:default",
|
|
||||||
"shell:allow-execute",
|
|
||||||
"dialog:default",
|
|
||||||
"core:window:allow-start-dragging",
|
|
||||||
"core:window:allow-minimize",
|
|
||||||
"core:window:allow-close",
|
|
||||||
"cors-fetch:default",
|
|
||||||
"core:window:allow-hide",
|
|
||||||
"core:window:allow-show",
|
|
||||||
"fs:default",
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-read",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-write",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-exists",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-read-file",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-write-file",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-read-text-file",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-mkdir",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-read-dir",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identifier": "fs:allow-remove",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$HOME/.ezpplauncher/**/*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_launcher_background">#fff</color>
|
|
||||||
</resources>
|
|
||||||
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 357 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 24 KiB |
@@ -1,6 +0,0 @@
|
|||||||
!macro NSIS_HOOK_POSTINSTALL
|
|
||||||
${If} $PassiveMode = 1
|
|
||||||
${OrIf} ${Silent}
|
|
||||||
Exec '"$INSTDIR\${MAINBINARYNAME}.exe"'
|
|
||||||
${EndIf}
|
|
||||||
!macroend
|
|
||||||
@@ -1,931 +0,0 @@
|
|||||||
use hardware_id::get_id;
|
|
||||||
use reqwest::Client;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use sysinfo::System;
|
|
||||||
use tauri::AppHandle;
|
|
||||||
use tauri::Emitter;
|
|
||||||
use tauri::Manager;
|
|
||||||
use tokio::fs;
|
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
use tokio::process::Command;
|
|
||||||
use tokio::time::{Duration, sleep};
|
|
||||||
|
|
||||||
use crate::osudb::parse_osudb;
|
|
||||||
use crate::presence;
|
|
||||||
use crate::utils::{
|
|
||||||
check_folder_completeness, encrypt_password, get_osu_config, get_osu_user_config,
|
|
||||||
get_window_title_by_pid, is_net8_installed, is_osuwinello_available, is_wmctrl_available,
|
|
||||||
set_osu_config_vals, set_osu_user_config_vals,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_launcher_version() -> String {
|
|
||||||
env!("CARGO_PKG_VERSION").to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_hwid() -> String {
|
|
||||||
let hwid = get_id().unwrap();
|
|
||||||
hwid.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command(rename_all = "snake_case")]
|
|
||||||
pub fn valid_osu_folder(folder: String) -> bool {
|
|
||||||
let osu_folder_files = [
|
|
||||||
"avcodec-51.dll",
|
|
||||||
"avformat-52.dll",
|
|
||||||
"avutil-49.dll",
|
|
||||||
"bass.dll",
|
|
||||||
"bass_fx.dll",
|
|
||||||
"collection.db",
|
|
||||||
"d3dcompiler_47.dll",
|
|
||||||
"libEGL.dll",
|
|
||||||
"libGLESv2.dll",
|
|
||||||
"Microsoft.Ink.dll",
|
|
||||||
"OpenTK.dll",
|
|
||||||
"osu!.cfg",
|
|
||||||
"osu!.db",
|
|
||||||
"osu!.exe",
|
|
||||||
"osu!auth.dll",
|
|
||||||
"osu!gameplay.dll",
|
|
||||||
"osu!seasonal.dll",
|
|
||||||
"osu!ui.dll",
|
|
||||||
"presence.db",
|
|
||||||
"pthreadGC2.dll",
|
|
||||||
"scores.db",
|
|
||||||
];
|
|
||||||
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
if !path.join("osu!.exe").exists() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
check_folder_completeness(path, &osu_folder_files) >= 70.0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn find_osu_installation() -> Option<String> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn find_osu_installation() -> Option<String> {
|
|
||||||
use winreg::RegKey;
|
|
||||||
use winreg::enums::*;
|
|
||||||
|
|
||||||
let hklm_registry_paths = ["SOFTWARE\\Classes\\osu\\DefaultIcon"];
|
|
||||||
|
|
||||||
let hkcu_registry_paths = [
|
|
||||||
"Software\\Classes\\osustable.File.osk\\DefaultIcon",
|
|
||||||
"Software\\Classes\\osustable.File.osr\\DefaultIcon",
|
|
||||||
"Software\\Classes\\osustable.File.osz\\DefaultIcon",
|
|
||||||
];
|
|
||||||
|
|
||||||
let osu_folder_files = [
|
|
||||||
"avcodec-51.dll",
|
|
||||||
"avformat-52.dll",
|
|
||||||
"avutil-49.dll",
|
|
||||||
"bass.dll",
|
|
||||||
"bass_fx.dll",
|
|
||||||
"collection.db",
|
|
||||||
"d3dcompiler_47.dll",
|
|
||||||
"libEGL.dll",
|
|
||||||
"libGLESv2.dll",
|
|
||||||
"Microsoft.Ink.dll",
|
|
||||||
"OpenTK.dll",
|
|
||||||
"osu!.cfg",
|
|
||||||
"osu!.db",
|
|
||||||
"osu!.exe",
|
|
||||||
"osu!auth.dll",
|
|
||||||
"osu!gameplay.dll",
|
|
||||||
"osu!seasonal.dll",
|
|
||||||
"osu!ui.dll",
|
|
||||||
"presence.db",
|
|
||||||
"pthreadGC2.dll",
|
|
||||||
"scores.db",
|
|
||||||
];
|
|
||||||
|
|
||||||
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
|
|
||||||
|
|
||||||
for reg_path in &hklm_registry_paths {
|
|
||||||
if let Ok(subkey) = hklm.open_subkey_with_flags(reg_path, KEY_READ | KEY_WOW64_32KEY) {
|
|
||||||
let value_names = [""];
|
|
||||||
for value_name in &value_names {
|
|
||||||
if let Ok(value) = subkey.get_value::<String, _>(value_name) {
|
|
||||||
let trimmed = value.trim_matches('"');
|
|
||||||
let stripped = trimmed.strip_suffix(",0").unwrap_or(trimmed);
|
|
||||||
let path = PathBuf::from(stripped.trim());
|
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
let match_percentage = check_folder_completeness(parent, &osu_folder_files);
|
|
||||||
|
|
||||||
if match_percentage >= 70.0 {
|
|
||||||
return Some(parent.to_string_lossy().into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
|
||||||
|
|
||||||
for reg_path in &hkcu_registry_paths {
|
|
||||||
if let Ok(subkey) = hkcu.open_subkey_with_flags(reg_path, KEY_READ | KEY_WOW64_32KEY) {
|
|
||||||
let value_names = [""];
|
|
||||||
for value_name in &value_names {
|
|
||||||
if let Ok(value) = subkey.get_value::<String, _>(value_name) {
|
|
||||||
let trimmed = value.trim_matches('"');
|
|
||||||
let stripped = trimmed.strip_suffix(",1").unwrap_or(trimmed);
|
|
||||||
let path = PathBuf::from(stripped.trim());
|
|
||||||
if let Some(parent) = path.parent() {
|
|
||||||
let match_percentage = check_folder_completeness(parent, &osu_folder_files);
|
|
||||||
|
|
||||||
if match_percentage >= 70.0 {
|
|
||||||
return Some(parent.to_string_lossy().into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn get_beatmapsets_count(folder: String) -> Option<u64> {
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
let osu_db_path = path.join("osu!.db");
|
|
||||||
if !osu_db_path.exists() {
|
|
||||||
return Some(0);
|
|
||||||
}
|
|
||||||
let osu_db_bytes = fs::read(osu_db_path).await.ok()?;
|
|
||||||
let osu_db = parse_osudb(osu_db_bytes).ok()?;
|
|
||||||
let beatmap_sets = osu_db.beatmaps.iter().map(|b| b.beatmapset_id).collect::<HashSet<_>>().len();
|
|
||||||
Some(beatmap_sets as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct SkinInfo {
|
|
||||||
pub name: String,
|
|
||||||
pub author: Option<String>,
|
|
||||||
pub modified: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn get_skins(folder: String) -> Option<Vec<SkinInfo>> {
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::time::UNIX_EPOCH;
|
|
||||||
use tokio::fs;
|
|
||||||
|
|
||||||
let skins_folder = PathBuf::from(folder).join("Skins");
|
|
||||||
|
|
||||||
if !skins_folder.exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut entries = fs::read_dir(skins_folder).await.ok()?;
|
|
||||||
|
|
||||||
let mut skins = Vec::new();
|
|
||||||
|
|
||||||
while let Some(entry) = entries.next_entry().await.ok()? {
|
|
||||||
if !entry.file_type().await.ok()?.is_dir() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let dir_path = entry.path();
|
|
||||||
let skin_ini = dir_path.join("skin.ini");
|
|
||||||
|
|
||||||
if !skin_ini.exists() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = entry.file_name().to_string_lossy().to_string();
|
|
||||||
|
|
||||||
let author = fs::read_to_string(&skin_ini)
|
|
||||||
.await
|
|
||||||
.ok()
|
|
||||||
.and_then(|content| {
|
|
||||||
content.lines().find_map(|line| {
|
|
||||||
let (key, value) = line.split_once(':')?;
|
|
||||||
key.trim()
|
|
||||||
.eq_ignore_ascii_case("Author")
|
|
||||||
.then(|| value.trim().to_string())
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
let modified = entry
|
|
||||||
.metadata()
|
|
||||||
.await
|
|
||||||
.ok()
|
|
||||||
.and_then(|m| m.modified().ok())
|
|
||||||
.and_then(|t| t.duration_since(UNIX_EPOCH).ok())
|
|
||||||
.map(|d| d.as_secs())
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
skins.push(SkinInfo {
|
|
||||||
name,
|
|
||||||
author,
|
|
||||||
modified,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(skins)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn get_skins_count(folder: String) -> Option<u64> {
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
let skins_folder = path.join("Skins");
|
|
||||||
|
|
||||||
if !skins_folder.exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut count = 0;
|
|
||||||
if let Ok(mut entries) = fs::read_dir(skins_folder).await {
|
|
||||||
while let Ok(Some(entry)) = entries.next_entry().await {
|
|
||||||
if entry.file_type().await.map_or(false, |ft| ft.is_dir()) {
|
|
||||||
let dir_path = entry.path();
|
|
||||||
if let Ok(mut files) = fs::read_dir(&dir_path).await {
|
|
||||||
while let Ok(Some(file)) = files.next_entry().await {
|
|
||||||
if file.path().extension().map_or(false, |ext| ext == "ini") {
|
|
||||||
count += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Some(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_osu_skin(folder: String) -> String {
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
let osu_user_config = get_osu_user_config(path);
|
|
||||||
osu_user_config
|
|
||||||
.and_then(|config| config.get("Skin").cloned())
|
|
||||||
.unwrap_or_else(|| "Default".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_osu_version(folder: String) -> String {
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
let osu_user_config = get_osu_user_config(path);
|
|
||||||
osu_user_config
|
|
||||||
.and_then(|config| config.get("LastVersion").cloned())
|
|
||||||
.unwrap_or_else(|| "failed".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_osu_release_stream(folder: String) -> String {
|
|
||||||
let path = PathBuf::from(folder);
|
|
||||||
let osu_config = get_osu_config(path);
|
|
||||||
osu_config
|
|
||||||
.and_then(|config| config.get("_ReleaseStream").cloned())
|
|
||||||
.unwrap_or_else(|| "Stable40".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
|
||||||
pub struct ConfigEntry {
|
|
||||||
pub key: String,
|
|
||||||
pub value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn set_osu_user_config_values(
|
|
||||||
osu_folder_path: String,
|
|
||||||
entries: Vec<ConfigEntry>,
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
let converted: Vec<(&str, Option<&str>)> = entries
|
|
||||||
.iter()
|
|
||||||
.map(|entry| (entry.key.as_str(), Some(entry.value.as_str())))
|
|
||||||
.collect();
|
|
||||||
Ok(set_osu_user_config_vals(&osu_folder_path, &converted).is_ok())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn set_osu_config_values(
|
|
||||||
osu_folder_path: String,
|
|
||||||
entries: Vec<ConfigEntry>,
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
let converted: Vec<(&str, Option<&str>)> = entries
|
|
||||||
.iter()
|
|
||||||
.map(|entry| (entry.key.as_str(), Some(entry.value.as_str())))
|
|
||||||
.collect();
|
|
||||||
Ok(set_osu_config_vals(&osu_folder_path, &converted).is_ok())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn run_osu_updater(folder: String) -> Result<(), String> {
|
|
||||||
let mut updater_process = {
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
|
||||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
|
||||||
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
|
||||||
Command::new(&osu_exe_path)
|
|
||||||
.arg("-repair")
|
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
{
|
|
||||||
Command::new("osu-wine")
|
|
||||||
.arg("-repair")
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to spawn updater: {}", e))?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sleep(Duration::from_millis(500)).await;
|
|
||||||
|
|
||||||
let mut sys = System::new_all();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
|
||||||
|
|
||||||
let mut found = false;
|
|
||||||
|
|
||||||
for (_pid, process) in sys.processes() {
|
|
||||||
if process.name() == "osu!.exe" {
|
|
||||||
let pid = process.pid();
|
|
||||||
let title = get_window_title_by_pid(pid);
|
|
||||||
|
|
||||||
if !title.is_empty() && !title.contains("updater") {
|
|
||||||
let _ = process.kill_and_wait();
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if found {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep(Duration::from_millis(500)).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = updater_process.wait().await;
|
|
||||||
|
|
||||||
let force_update_files = [".require_update", "help.txt", "_pending"];
|
|
||||||
for update_file_name in &force_update_files {
|
|
||||||
let path = PathBuf::from(&folder).join(update_file_name);
|
|
||||||
if path.exists() {
|
|
||||||
match std::fs::symlink_metadata(&path) {
|
|
||||||
Ok(meta) => {
|
|
||||||
let res = if meta.is_dir() {
|
|
||||||
std::fs::remove_dir_all(&path)
|
|
||||||
} else {
|
|
||||||
std::fs::remove_file(&path)
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(e) = res {
|
|
||||||
eprintln!("Failed to remove {:?}: {}", path, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Could not stat {:?}: {}", path, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn run_osu(folder: String, patch: bool) -> Result<(), String> {
|
|
||||||
#[cfg(windows)]
|
|
||||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
|
||||||
#[cfg(windows)]
|
|
||||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
|
||||||
|
|
||||||
let mut game_process = {
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
let osu_exe_path = PathBuf::from(&folder).join("osu!.exe");
|
|
||||||
Command::new(&osu_exe_path)
|
|
||||||
.arg("-devserver")
|
|
||||||
.arg("ez-pp.farm")
|
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to spawn osu: {}", e))?
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
{
|
|
||||||
Command::new("osu-wine")
|
|
||||||
.arg("--devserver")
|
|
||||||
.arg("ez-pp.farm")
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to spawn osu: {}", e))?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if patch {
|
|
||||||
sleep(Duration::from_secs(3)).await;
|
|
||||||
|
|
||||||
let patcher_exe_path = PathBuf::from(&folder)
|
|
||||||
.join("EZPPLauncher")
|
|
||||||
.join("patcher")
|
|
||||||
.join("osu!.patcher.exe");
|
|
||||||
|
|
||||||
if patcher_exe_path.exists() {
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
let _ = Command::new(&patcher_exe_path)
|
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to run patcher: {e}"))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
game_process.wait().await.map_err(|e| e.to_string())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateFile {
|
|
||||||
pub name: String,
|
|
||||||
pub folder: String,
|
|
||||||
pub url: String,
|
|
||||||
pub size: usize,
|
|
||||||
pub md5: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn get_ezpp_launcher_update_files(
|
|
||||||
folder: String,
|
|
||||||
update_url: String,
|
|
||||||
update_stream: String,
|
|
||||||
) -> Result<(Vec<UpdateFile>, Vec<UpdateFile>), String> {
|
|
||||||
let osu_path = PathBuf::from(folder);
|
|
||||||
let client = Client::new();
|
|
||||||
|
|
||||||
let update_files = client
|
|
||||||
.patch(update_url)
|
|
||||||
.header("User-Agent", "EZPPLauncher")
|
|
||||||
.query(&[("stream", update_stream)])
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?
|
|
||||||
.json::<Vec<UpdateFile>>()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
let mut files_to_download = Vec::new();
|
|
||||||
|
|
||||||
for file in &update_files {
|
|
||||||
let file_path = osu_path.join(&file.folder).join(&file.name);
|
|
||||||
if file_path.exists() {
|
|
||||||
let data = fs::read(&file_path).await.map_err(|e| e.to_string())?;
|
|
||||||
let hash = format!("{:x}", md5::compute(&data));
|
|
||||||
if hash.to_lowercase() != file.md5.to_lowercase() {
|
|
||||||
files_to_download.push(file.clone());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
files_to_download.push(file.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((files_to_download, update_files))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateStatus {
|
|
||||||
pub file_name: String,
|
|
||||||
pub downloaded: u64,
|
|
||||||
pub size: usize,
|
|
||||||
pub progress: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn download_ezpp_launcher_update_files(
|
|
||||||
app: AppHandle,
|
|
||||||
folder: String,
|
|
||||||
update_files: Vec<UpdateFile>,
|
|
||||||
all_files: Vec<UpdateFile>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let osu_path = PathBuf::from(folder);
|
|
||||||
let client = Client::new();
|
|
||||||
|
|
||||||
let valid_paths: HashSet<PathBuf> = all_files
|
|
||||||
.iter()
|
|
||||||
.map(|f| osu_path.join(&f.folder).join(&f.name))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for folder in all_files
|
|
||||||
.iter()
|
|
||||||
.map(|f| osu_path.join(&f.folder))
|
|
||||||
.collect::<HashSet<_>>()
|
|
||||||
{
|
|
||||||
if folder.exists() && folder != osu_path {
|
|
||||||
let mut dir = fs::read_dir(&folder).await.map_err(|e| e.to_string())?;
|
|
||||||
while let Some(entry) = dir.next_entry().await.map_err(|e| e.to_string())? {
|
|
||||||
let path = entry.path();
|
|
||||||
if !valid_paths.contains(&path) {
|
|
||||||
fs::remove_file(&path).await.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for file in update_files {
|
|
||||||
let file_path = osu_path.join(&file.folder).join(&file.name);
|
|
||||||
let parent = file_path.parent().unwrap();
|
|
||||||
if !parent.exists() {
|
|
||||||
fs::create_dir_all(parent)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut response = client
|
|
||||||
.get(&file.url)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
let mut file_out = fs::File::create(&file_path)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
let mut downloaded = 0u64;
|
|
||||||
|
|
||||||
while let Some(chunk) = response.chunk().await.map_err(|e| e.to_string())? {
|
|
||||||
downloaded += chunk.len() as u64;
|
|
||||||
file_out
|
|
||||||
.write_all(&chunk)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
app.emit(
|
|
||||||
"download-progress",
|
|
||||||
UpdateStatus {
|
|
||||||
file_name: file.name.clone(),
|
|
||||||
downloaded,
|
|
||||||
size: file.size,
|
|
||||||
progress: ((downloaded as f64 / file.size as f64 * 100.0) * 100.0).trunc()
|
|
||||||
/ 100.0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap_or_default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
#[serde(tag = "type", content = "details")]
|
|
||||||
pub enum ReplaceUIError {
|
|
||||||
FileNotFound(String),
|
|
||||||
IoError(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn replace_ui_files(folder: String, revert: bool) -> Result<(), ReplaceUIError> {
|
|
||||||
let osu_path = PathBuf::from(folder);
|
|
||||||
let ezpp_ui = osu_path.join("EZPPLauncher").join("ezpp!ui.dll");
|
|
||||||
let osu_ui = osu_path.join("osu!ui.dll");
|
|
||||||
let ezpp_seasonal = osu_path.join("EZPPLauncher").join("ezpp!seasonal.dll");
|
|
||||||
let osu_seasonal = osu_path.join("osu!seasonal.dll");
|
|
||||||
let ezpp_gameplay = osu_path.join("EZPPLauncher").join("ezpp!gameplay.dll");
|
|
||||||
let osu_gameplay = osu_path.join("osu!gameplay.dll");
|
|
||||||
|
|
||||||
let osu_ui_bak = osu_path.join("osu!ui.dll.bak");
|
|
||||||
let osu_seasonal_bak = osu_path.join("osu!seasonal.dll.bak");
|
|
||||||
let osu_gameplay_bak = osu_path.join("osu!gameplay.dll.bak");
|
|
||||||
|
|
||||||
let temp_file = osu_path.join(".ezpplauncher_files");
|
|
||||||
|
|
||||||
let copy_file = |source: &PathBuf, dest: &PathBuf, name: &str| -> Result<(), ReplaceUIError> {
|
|
||||||
if !source.exists() {
|
|
||||||
return Err(ReplaceUIError::FileNotFound(source.display().to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if dest.exists() {
|
|
||||||
std::fs::remove_file(dest).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to remove {}: {}", name, e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fs::copy(source, dest)
|
|
||||||
.map_err(|e| ReplaceUIError::IoError(format!("Failed to copy {}: {}", name, e)))?;
|
|
||||||
Ok(())
|
|
||||||
};
|
|
||||||
|
|
||||||
let restore_backup =
|
|
||||||
|bak: &PathBuf, dest: &PathBuf, name: &str| -> Result<(), ReplaceUIError> {
|
|
||||||
if bak.exists() {
|
|
||||||
if dest.exists() {
|
|
||||||
std::fs::remove_file(dest).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to remove {}: {}", name, e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
std::fs::rename(bak, dest).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to rename {} from backup: {}", name, e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
};
|
|
||||||
|
|
||||||
if !revert {
|
|
||||||
if osu_ui.exists() && !osu_ui_bak.exists() {
|
|
||||||
std::fs::rename(&osu_ui, &osu_ui_bak).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to backup osu!ui.dll: {}", e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
if osu_seasonal.exists() && !osu_seasonal_bak.exists() {
|
|
||||||
std::fs::rename(&osu_seasonal, &osu_seasonal_bak).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to backup osu!seasonal.dll: {}", e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
if osu_gameplay.exists() && !osu_gameplay_bak.exists() {
|
|
||||||
std::fs::rename(&osu_gameplay, &osu_gameplay_bak).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to backup osu!gameplay.dll: {}", e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_file(&ezpp_ui, &osu_ui, "osu!ui.dll")?;
|
|
||||||
copy_file(&ezpp_seasonal, &osu_seasonal, "osu!seasonal.dll")?;
|
|
||||||
copy_file(&ezpp_gameplay, &osu_gameplay, "osu!gameplay.dll")?;
|
|
||||||
|
|
||||||
std::fs::write(&temp_file, b"1")
|
|
||||||
.map_err(|e| ReplaceUIError::IoError(format!("Failed to write marker file: {}", e)))?;
|
|
||||||
} else {
|
|
||||||
restore_backup(&osu_ui_bak, &osu_ui, "osu!ui.dll")?;
|
|
||||||
restore_backup(&osu_seasonal_bak, &osu_seasonal, "osu!seasonal.dll")?;
|
|
||||||
restore_backup(&osu_gameplay_bak, &osu_gameplay, "osu!gameplay.dll")?;
|
|
||||||
|
|
||||||
if osu_ui.exists() && osu_seasonal.exists() && osu_gameplay.exists() {
|
|
||||||
std::fs::remove_file(&temp_file).map_err(|e| {
|
|
||||||
ReplaceUIError::IoError(format!("Failed to remove marker file: {}", e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
#[serde(tag = "type", content = "details")]
|
|
||||||
pub enum CorruptionCheckError {
|
|
||||||
IoError(String),
|
|
||||||
FileNotFound(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn check_for_corruption(folder: String) -> Result<bool, CorruptionCheckError> {
|
|
||||||
let osu_path = PathBuf::from(folder);
|
|
||||||
let osu_ui = osu_path.join("osu!ui.dll");
|
|
||||||
let osu_gameplay = osu_path.join("osu!gameplay.dll");
|
|
||||||
let osu_seasonal = osu_path.join("osu!seasonal.dll");
|
|
||||||
|
|
||||||
let osu_ui_bak = osu_path.join("osu!ui.dll.bak");
|
|
||||||
let osu_gameplay_bak = osu_path.join("osu!gameplay.dll.bak");
|
|
||||||
let osu_seasonal_bak = osu_path.join("osu!seasonal.dll.bak");
|
|
||||||
|
|
||||||
let temp_file = osu_path.join(".ezpplauncher_files");
|
|
||||||
|
|
||||||
if temp_file.exists() {
|
|
||||||
if osu_ui_bak.exists() {
|
|
||||||
if osu_ui.exists() {
|
|
||||||
fs::remove_file(&osu_ui).await.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!("Failed to remove osu!ui.dll: {}", e))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::rename(&osu_ui_bak, &osu_ui).await.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!(
|
|
||||||
"Failed to restore osu!ui.dll from backup: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
if osu_gameplay_bak.exists() {
|
|
||||||
if osu_gameplay.exists() {
|
|
||||||
fs::remove_file(&osu_gameplay).await.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!(
|
|
||||||
"Failed to remove osu!gameplay.dll: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::rename(&osu_gameplay_bak, &osu_gameplay)
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!(
|
|
||||||
"Failed to restore osu!gameplay.dll from backup: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
if osu_seasonal_bak.exists() {
|
|
||||||
if osu_seasonal.exists() {
|
|
||||||
fs::remove_file(&osu_seasonal).await.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!(
|
|
||||||
"Failed to remove osu!seasonal.dll: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::rename(&osu_seasonal_bak, &osu_seasonal)
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
CorruptionCheckError::IoError(format!(
|
|
||||||
"Failed to restore osu!seasonal.dll from backup: {}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !osu_ui.exists() || !osu_gameplay.exists() || !osu_seasonal.exists() {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn is_osu_running() -> bool {
|
|
||||||
let mut sys = System::new_all();
|
|
||||||
sys.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
|
|
||||||
|
|
||||||
for process in sys.processes().values() {
|
|
||||||
if process.name().eq_ignore_ascii_case("osu!.exe") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn open_url_in_browser(url: String) -> Result<(), String> {
|
|
||||||
open::that(&url).map_err(|e| format!("Failed to open URL: {}", e))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn exit(app: AppHandle) {
|
|
||||||
app.exit(0x0100);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_platform() -> String {
|
|
||||||
std::env::consts::OS.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn presence_connect() -> bool {
|
|
||||||
presence::connect().await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn presence_disconnect() {
|
|
||||||
presence::disconnect().await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct PresenceStatus {
|
|
||||||
state: Option<String>,
|
|
||||||
details: Option<String>,
|
|
||||||
large_image_key: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn presence_update_status(status: PresenceStatus) {
|
|
||||||
presence::update_status(
|
|
||||||
status.state.as_deref(),
|
|
||||||
status.details.as_deref(),
|
|
||||||
status.large_image_key.as_deref(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct PresenceUser {
|
|
||||||
username: Option<String>,
|
|
||||||
id: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn presence_update_user(user: PresenceUser) {
|
|
||||||
presence::update_user(user.username.as_deref(), user.id.as_deref());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn presence_is_connected() -> bool {
|
|
||||||
presence::has_presence().await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn has_wmctrl() -> bool {
|
|
||||||
is_wmctrl_available()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn has_osuwinello() -> bool {
|
|
||||||
is_osuwinello_available()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn has_net8() -> bool {
|
|
||||||
is_net8_installed().await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn encrypt_string(string: String, entropy: String) -> String {
|
|
||||||
encrypt_password(&string, &entropy).unwrap_or(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn download_ezpp_launcher_update(app: AppHandle, url: String) -> Result<(), String> {
|
|
||||||
let client = Client::new();
|
|
||||||
|
|
||||||
let mut response = client.get(&url).send().await.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
if !response.status().is_success() {
|
|
||||||
return Err(format!("Failed to download update: {}", response.status()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let temp_dir = app.path().temp_dir().expect("Failed to get temp directory");
|
|
||||||
let file_path = temp_dir.join("ezpplauncher_update.exe");
|
|
||||||
|
|
||||||
let mut file_out = fs::File::create(&file_path)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
let mut downloaded = 0u64;
|
|
||||||
let size = response
|
|
||||||
.content_length()
|
|
||||||
.ok_or("Failed to get content length")? as usize;
|
|
||||||
|
|
||||||
while let Some(chunk) = response.chunk().await.map_err(|e| e.to_string())? {
|
|
||||||
downloaded += chunk.len() as u64;
|
|
||||||
file_out
|
|
||||||
.write_all(&chunk)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
app.emit(
|
|
||||||
"download-progress",
|
|
||||||
UpdateStatus {
|
|
||||||
file_name: "Update".to_string(),
|
|
||||||
downloaded,
|
|
||||||
size,
|
|
||||||
progress: ((downloaded as f64 / size as f64 * 100.0) * 100.0).trunc() / 100.0,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap_or_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn install_ezpp_launcher_update(app: AppHandle) -> Result<(), String> {
|
|
||||||
let temp_dir = app.path().temp_dir().expect("Failed to get temp directory");
|
|
||||||
let file_path = temp_dir.join("ezpplauncher_update.exe");
|
|
||||||
if !file_path.exists() {
|
|
||||||
return Err("Update file does not exist".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
// run this app detached and exit
|
|
||||||
|
|
||||||
const DETACHED_PROCESS: u32 = 0x00000008;
|
|
||||||
const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
|
|
||||||
|
|
||||||
Command::new(&file_path)
|
|
||||||
.arg("/S")
|
|
||||||
.creation_flags(DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP)
|
|
||||||
.spawn()
|
|
||||||
.map_err(|e| format!("Failed to spawn updater: {}", e))?;
|
|
||||||
|
|
||||||
sleep(Duration::from_millis(250)).await;
|
|
||||||
|
|
||||||
app.exit(0x0100);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn install_ezpp_launcher_update(_app: AppHandle) -> Result<(), String> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
||||||
use tauri::Manager;
|
|
||||||
|
|
||||||
pub mod commands;
|
|
||||||
pub mod presence;
|
|
||||||
pub mod utils;
|
|
||||||
pub mod osudb;
|
|
||||||
use crate::commands::{
|
|
||||||
check_for_corruption, download_ezpp_launcher_update, download_ezpp_launcher_update_files,
|
|
||||||
encrypt_string, exit, find_osu_installation, get_beatmapsets_count,
|
|
||||||
get_ezpp_launcher_update_files, get_hwid, get_launcher_version, get_osu_release_stream,
|
|
||||||
get_osu_skin, get_osu_version, get_platform, get_skins, get_skins_count, has_net8,
|
|
||||||
has_osuwinello, has_wmctrl, install_ezpp_launcher_update, is_osu_running, open_url_in_browser,
|
|
||||||
presence_connect, presence_disconnect, presence_is_connected, presence_update_status,
|
|
||||||
presence_update_user, replace_ui_files, run_osu, run_osu_updater, set_osu_config_values,
|
|
||||||
set_osu_user_config_values, valid_osu_folder,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
||||||
pub fn run() {
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
unsafe {
|
|
||||||
// std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut builder = tauri::Builder::default();
|
|
||||||
#[cfg(desktop)]
|
|
||||||
{
|
|
||||||
builder = builder.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
|
||||||
let app_window = app.get_webview_window("main").expect("no main window");
|
|
||||||
app_window.set_focus().expect("failed to focus");
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let app = builder
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
|
||||||
get_hwid,
|
|
||||||
find_osu_installation,
|
|
||||||
valid_osu_folder,
|
|
||||||
get_beatmapsets_count,
|
|
||||||
get_skins,
|
|
||||||
get_skins_count,
|
|
||||||
get_osu_version,
|
|
||||||
get_osu_release_stream,
|
|
||||||
set_osu_config_values,
|
|
||||||
set_osu_user_config_values,
|
|
||||||
run_osu_updater,
|
|
||||||
run_osu,
|
|
||||||
get_osu_skin,
|
|
||||||
get_ezpp_launcher_update_files,
|
|
||||||
download_ezpp_launcher_update_files,
|
|
||||||
replace_ui_files,
|
|
||||||
is_osu_running,
|
|
||||||
open_url_in_browser,
|
|
||||||
get_launcher_version,
|
|
||||||
exit,
|
|
||||||
get_platform,
|
|
||||||
check_for_corruption,
|
|
||||||
presence_connect,
|
|
||||||
presence_disconnect,
|
|
||||||
presence_update_status,
|
|
||||||
presence_update_user,
|
|
||||||
presence_is_connected,
|
|
||||||
has_osuwinello,
|
|
||||||
has_wmctrl,
|
|
||||||
has_net8,
|
|
||||||
encrypt_string,
|
|
||||||
download_ezpp_launcher_update,
|
|
||||||
install_ezpp_launcher_update
|
|
||||||
])
|
|
||||||
.plugin(tauri_plugin_fs::init())
|
|
||||||
.plugin(tauri_plugin_dialog::init())
|
|
||||||
.plugin(tauri_plugin_shell::init())
|
|
||||||
.plugin(tauri_plugin_cors_fetch::init())
|
|
||||||
.build(tauri::generate_context!())
|
|
||||||
.expect("error while building tauri application");
|
|
||||||
|
|
||||||
app.run(|_app_handle, event| {
|
|
||||||
if let tauri::RunEvent::ExitRequested { api, .. } = event {
|
|
||||||
api.prevent_exit();
|
|
||||||
|
|
||||||
tauri::async_runtime::block_on(presence::disconnect());
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
ezpplauncher_lib::run()
|
|
||||||
}
|
|
||||||
@@ -1,370 +0,0 @@
|
|||||||
use std::io::{Cursor, Read};
|
|
||||||
|
|
||||||
use anyhow::{Result, anyhow};
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub struct OsuReader {
|
|
||||||
cursor: Cursor<Vec<u8>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OsuReader {
|
|
||||||
pub fn new(data: Vec<u8>) -> Self {
|
|
||||||
Self {
|
|
||||||
cursor: Cursor::new(data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_i16(&mut self) -> Result<i16> {
|
|
||||||
Ok(self.cursor.read_i16::<LittleEndian>()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_i32(&mut self) -> Result<i32> {
|
|
||||||
Ok(self.cursor.read_i32::<LittleEndian>()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_i64(&mut self) -> Result<i64> {
|
|
||||||
Ok(self.cursor.read_i64::<LittleEndian>()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u8(&mut self) -> Result<u8> {
|
|
||||||
Ok(self.cursor.read_u8()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_f32(&mut self) -> Result<f32> {
|
|
||||||
Ok(self.cursor.read_f32::<LittleEndian>()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_f64(&mut self) -> Result<f64> {
|
|
||||||
Ok(self.cursor.read_f64::<LittleEndian>()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_bool(&mut self) -> Result<bool> {
|
|
||||||
Ok(self.read_u8()? != 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_string(&mut self) -> Result<Option<String>> {
|
|
||||||
let indicator = self.read_u8()?;
|
|
||||||
|
|
||||||
if indicator == 0 {
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
if indicator != 0x0B {
|
|
||||||
return Err(anyhow!("Invalid osu string indicator"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let len = self.read_uleb128()? as usize;
|
|
||||||
let mut buf = vec![0; len];
|
|
||||||
self.cursor.read_exact(&mut buf)?;
|
|
||||||
|
|
||||||
Ok(Some(String::from_utf8(buf)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_uleb128(&mut self) -> Result<u64> {
|
|
||||||
let mut result = 0;
|
|
||||||
let mut shift = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let byte = self.read_u8()?;
|
|
||||||
result |= ((byte & 0x7F) as u64) << shift;
|
|
||||||
|
|
||||||
if (byte & 0x80) == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
shift += 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TimingPoint {
|
|
||||||
pub bpm: f64,
|
|
||||||
pub offset: f64,
|
|
||||||
pub inherited: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Beatmap {
|
|
||||||
pub artist_name: Option<String>,
|
|
||||||
pub artist_unicode: Option<String>,
|
|
||||||
pub song_title: Option<String>,
|
|
||||||
pub song_title_unicode: Option<String>,
|
|
||||||
pub creator: Option<String>,
|
|
||||||
pub difficulty: Option<String>,
|
|
||||||
pub audio: Option<String>,
|
|
||||||
pub md5: Option<String>,
|
|
||||||
pub osu_file_name: Option<String>,
|
|
||||||
|
|
||||||
pub ranked_status: u8,
|
|
||||||
pub hitcircles: i16,
|
|
||||||
pub slider_count: i16,
|
|
||||||
pub spinner_count: i16,
|
|
||||||
pub last_modification: i64,
|
|
||||||
|
|
||||||
pub approach_rate: f32,
|
|
||||||
pub circle_size: f32,
|
|
||||||
pub hp_drain: f32,
|
|
||||||
pub overall_difficulty: f32,
|
|
||||||
pub slider_velocity: f64,
|
|
||||||
|
|
||||||
pub difficulties: HashMap<i32, f64>,
|
|
||||||
|
|
||||||
pub drain_time: i32,
|
|
||||||
pub total_time: i32,
|
|
||||||
pub preview_offset: i32,
|
|
||||||
|
|
||||||
pub beatmap_id: i32,
|
|
||||||
pub beatmapset_id: i32,
|
|
||||||
pub thread_id: i32,
|
|
||||||
|
|
||||||
pub grade_standard: u8,
|
|
||||||
pub grade_taiko: u8,
|
|
||||||
pub grade_catch: u8,
|
|
||||||
pub grade_mania: u8,
|
|
||||||
|
|
||||||
pub local_beatmap_offset: i16,
|
|
||||||
pub stack_leniency: f32,
|
|
||||||
|
|
||||||
pub mode: u8,
|
|
||||||
pub song_source: Option<String>,
|
|
||||||
pub song_tags: Option<String>,
|
|
||||||
|
|
||||||
pub online_beatmap_offset: i16,
|
|
||||||
pub title_font: Option<String>,
|
|
||||||
|
|
||||||
pub unplayed: bool,
|
|
||||||
pub last_played: i64,
|
|
||||||
pub osz2: bool,
|
|
||||||
pub folder_name: Option<String>,
|
|
||||||
pub last_checked_against_repository: i64,
|
|
||||||
|
|
||||||
pub ignore_sound: bool,
|
|
||||||
pub ignore_skin: bool,
|
|
||||||
pub disable_storyboard: bool,
|
|
||||||
pub disable_video: bool,
|
|
||||||
pub visual_override: bool,
|
|
||||||
|
|
||||||
pub last_modification_time: i32,
|
|
||||||
pub mania_scroll_speed: u8,
|
|
||||||
|
|
||||||
pub timing_points: Vec<TimingPoint>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct OsuDbData {
|
|
||||||
pub osuver: i32,
|
|
||||||
pub folder_count: i32,
|
|
||||||
pub is_unlocked: bool,
|
|
||||||
pub date_unlock_ticks: i64,
|
|
||||||
pub username: Option<String>,
|
|
||||||
pub beatmaps: Vec<Beatmap>,
|
|
||||||
pub userperms: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// =========================
|
|
||||||
// PARSER
|
|
||||||
// =========================
|
|
||||||
//
|
|
||||||
|
|
||||||
pub fn parse_osudb(bytes: Vec<u8>) -> Result<OsuDbData> {
|
|
||||||
let mut reader = OsuReader::new(bytes);
|
|
||||||
|
|
||||||
let osuver = reader.read_i32()?;
|
|
||||||
let folder_count = reader.read_i32()?;
|
|
||||||
let is_unlocked = reader.read_bool()?;
|
|
||||||
let date_unlock_ticks = reader.read_i64()?;
|
|
||||||
let username = reader.read_string()?;
|
|
||||||
let beatmaps_count = reader.read_i32()?;
|
|
||||||
|
|
||||||
let mut beatmaps = Vec::new();
|
|
||||||
|
|
||||||
for _ in 0..beatmaps_count {
|
|
||||||
if osuver < 20191107 {
|
|
||||||
reader.read_i32()?; // entry size
|
|
||||||
}
|
|
||||||
|
|
||||||
let artist_name = reader.read_string()?;
|
|
||||||
let artist_unicode = reader.read_string()?;
|
|
||||||
let song_title = reader.read_string()?;
|
|
||||||
let song_title_unicode = reader.read_string()?;
|
|
||||||
let creator = reader.read_string()?;
|
|
||||||
let difficulty = reader.read_string()?;
|
|
||||||
let audio = reader.read_string()?;
|
|
||||||
let md5 = reader.read_string()?;
|
|
||||||
let osu_file_name = reader.read_string()?;
|
|
||||||
|
|
||||||
let ranked_status = reader.read_u8()?;
|
|
||||||
let hitcircles = reader.read_i16()?;
|
|
||||||
let slider_count = reader.read_i16()?;
|
|
||||||
let spinner_count = reader.read_i16()?;
|
|
||||||
let last_modification = reader.read_i64()?;
|
|
||||||
|
|
||||||
let approach_rate = if osuver < 20140609 {
|
|
||||||
reader.read_u8()? as f32
|
|
||||||
} else {
|
|
||||||
reader.read_f32()?
|
|
||||||
};
|
|
||||||
|
|
||||||
let circle_size = if osuver < 20140609 {
|
|
||||||
reader.read_u8()? as f32
|
|
||||||
} else {
|
|
||||||
reader.read_f32()?
|
|
||||||
};
|
|
||||||
|
|
||||||
let hp_drain = if osuver < 20140609 {
|
|
||||||
reader.read_u8()? as f32
|
|
||||||
} else {
|
|
||||||
reader.read_f32()?
|
|
||||||
};
|
|
||||||
|
|
||||||
let overall_difficulty = if osuver < 20140609 {
|
|
||||||
reader.read_u8()? as f32
|
|
||||||
} else {
|
|
||||||
reader.read_f32()?
|
|
||||||
};
|
|
||||||
|
|
||||||
let slider_velocity = reader.read_f64()?;
|
|
||||||
|
|
||||||
let mut difficulties: HashMap<i32, f64> = HashMap::new();
|
|
||||||
|
|
||||||
if osuver >= 20140609 {
|
|
||||||
for _ in 0..4 {
|
|
||||||
let len = reader.read_i32()?;
|
|
||||||
for _ in 0..len {
|
|
||||||
reader.read_u8()?;
|
|
||||||
let mode = reader.read_i32()?;
|
|
||||||
reader.read_u8()?;
|
|
||||||
let diff = if osuver > 20250107 {
|
|
||||||
reader.read_f32()? as f64
|
|
||||||
} else {
|
|
||||||
reader.read_f64()?
|
|
||||||
};
|
|
||||||
|
|
||||||
difficulties.insert(mode, diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let drain_time = reader.read_i32()?;
|
|
||||||
let total_time = reader.read_i32()?;
|
|
||||||
let preview_offset = reader.read_i32()?;
|
|
||||||
|
|
||||||
let timing_len = reader.read_i32()?;
|
|
||||||
let mut timing_points = Vec::new();
|
|
||||||
for _ in 0..timing_len {
|
|
||||||
timing_points.push(TimingPoint {
|
|
||||||
bpm: reader.read_f64()?,
|
|
||||||
offset: reader.read_f64()?,
|
|
||||||
inherited: reader.read_bool()?,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let beatmap_id = reader.read_i32()?;
|
|
||||||
let beatmapset_id = reader.read_i32()?;
|
|
||||||
let thread_id = reader.read_i32()?;
|
|
||||||
|
|
||||||
let grade_standard = reader.read_u8()?;
|
|
||||||
let grade_taiko = reader.read_u8()?;
|
|
||||||
let grade_catch = reader.read_u8()?;
|
|
||||||
let grade_mania = reader.read_u8()?;
|
|
||||||
|
|
||||||
let local_beatmap_offset = reader.read_i16()?;
|
|
||||||
let stack_leniency = reader.read_f32()?;
|
|
||||||
|
|
||||||
let mode = reader.read_u8()?;
|
|
||||||
let song_source = reader.read_string()?;
|
|
||||||
let song_tags = reader.read_string()?;
|
|
||||||
|
|
||||||
let online_beatmap_offset = reader.read_i16()?;
|
|
||||||
let title_font = reader.read_string()?;
|
|
||||||
|
|
||||||
let unplayed = reader.read_bool()?;
|
|
||||||
let last_played = reader.read_i64()?;
|
|
||||||
let osz2 = reader.read_bool()?;
|
|
||||||
let folder_name = reader.read_string()?;
|
|
||||||
let last_checked_against_repository = reader.read_i64()?;
|
|
||||||
|
|
||||||
let ignore_sound = reader.read_bool()?;
|
|
||||||
let ignore_skin = reader.read_bool()?;
|
|
||||||
let disable_storyboard = reader.read_bool()?;
|
|
||||||
let disable_video = reader.read_bool()?;
|
|
||||||
let visual_override = reader.read_bool()?;
|
|
||||||
|
|
||||||
if osuver < 20140609 {
|
|
||||||
reader.read_i16()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let last_modification_time = reader.read_i32()?;
|
|
||||||
let mania_scroll_speed = reader.read_u8()?;
|
|
||||||
|
|
||||||
beatmaps.push(Beatmap {
|
|
||||||
artist_name,
|
|
||||||
artist_unicode,
|
|
||||||
song_title,
|
|
||||||
song_title_unicode,
|
|
||||||
creator,
|
|
||||||
difficulty,
|
|
||||||
audio,
|
|
||||||
md5,
|
|
||||||
osu_file_name,
|
|
||||||
ranked_status,
|
|
||||||
hitcircles,
|
|
||||||
slider_count,
|
|
||||||
spinner_count,
|
|
||||||
last_modification,
|
|
||||||
approach_rate,
|
|
||||||
circle_size,
|
|
||||||
hp_drain,
|
|
||||||
overall_difficulty,
|
|
||||||
slider_velocity,
|
|
||||||
difficulties,
|
|
||||||
drain_time,
|
|
||||||
total_time,
|
|
||||||
preview_offset,
|
|
||||||
beatmap_id,
|
|
||||||
beatmapset_id,
|
|
||||||
thread_id,
|
|
||||||
grade_standard,
|
|
||||||
grade_taiko,
|
|
||||||
grade_catch,
|
|
||||||
grade_mania,
|
|
||||||
local_beatmap_offset,
|
|
||||||
stack_leniency,
|
|
||||||
mode,
|
|
||||||
song_source,
|
|
||||||
song_tags,
|
|
||||||
online_beatmap_offset,
|
|
||||||
title_font,
|
|
||||||
unplayed,
|
|
||||||
last_played,
|
|
||||||
osz2,
|
|
||||||
folder_name,
|
|
||||||
last_checked_against_repository,
|
|
||||||
ignore_sound,
|
|
||||||
ignore_skin,
|
|
||||||
disable_storyboard,
|
|
||||||
disable_video,
|
|
||||||
visual_override,
|
|
||||||
last_modification_time,
|
|
||||||
mania_scroll_speed,
|
|
||||||
timing_points,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let userperms = reader.read_i32()?;
|
|
||||||
|
|
||||||
Ok(OsuDbData {
|
|
||||||
osuver,
|
|
||||||
folder_count,
|
|
||||||
is_unlocked,
|
|
||||||
date_unlock_ticks,
|
|
||||||
username,
|
|
||||||
beatmaps,
|
|
||||||
userperms,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,271 +0,0 @@
|
|||||||
use discord_rich_presence::{
|
|
||||||
DiscordIpc, DiscordIpcClient,
|
|
||||||
activity::{Activity, Assets, Button, Timestamps},
|
|
||||||
};
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use std::future::Future;
|
|
||||||
use std::pin::Pin;
|
|
||||||
use std::sync::Mutex as StdMutex;
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
|
||||||
use tokio::sync::{mpsc, oneshot};
|
|
||||||
use tokio::time::{Duration, interval};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct PresenceData {
|
|
||||||
pub state: String,
|
|
||||||
pub details: String,
|
|
||||||
pub large_image_key: String,
|
|
||||||
pub large_image_text: String,
|
|
||||||
pub small_image_key: Option<String>,
|
|
||||||
pub small_image_text: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum PresenceCommand {
|
|
||||||
Connect(oneshot::Sender<bool>),
|
|
||||||
Disconnect(oneshot::Sender<()>),
|
|
||||||
UpdateData(PresenceData),
|
|
||||||
IsConnected(oneshot::Sender<bool>),
|
|
||||||
Tick,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PresenceActor {
|
|
||||||
receiver: mpsc::Receiver<PresenceCommand>,
|
|
||||||
client: Option<DiscordIpcClient>,
|
|
||||||
data: PresenceData,
|
|
||||||
start_timestamp: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PresenceActor {
|
|
||||||
fn new(receiver: mpsc::Receiver<PresenceCommand>) -> Self {
|
|
||||||
let start = SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs() as i64;
|
|
||||||
|
|
||||||
let data = PresenceData {
|
|
||||||
state: "Idle in Launcher...".to_string(),
|
|
||||||
details: " ".to_string(),
|
|
||||||
large_image_key: "ezppfarm".to_string(),
|
|
||||||
large_image_text: "EZPPFarm".to_string(),
|
|
||||||
small_image_key: None,
|
|
||||||
small_image_text: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
PresenceActor {
|
|
||||||
receiver,
|
|
||||||
client: None,
|
|
||||||
data,
|
|
||||||
start_timestamp: start,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run(&mut self) {
|
|
||||||
let mut update_interval = interval(Duration::from_secs(5));
|
|
||||||
|
|
||||||
loop {
|
|
||||||
tokio::select! {
|
|
||||||
Some(cmd) = self.receiver.recv() => {
|
|
||||||
match cmd {
|
|
||||||
PresenceCommand::Connect(responder) => self.handle_connect(responder).await,
|
|
||||||
PresenceCommand::Disconnect(responder) => {
|
|
||||||
self.handle_disconnect(responder).await;
|
|
||||||
},
|
|
||||||
PresenceCommand::UpdateData(new_data) => {
|
|
||||||
self.data = new_data;
|
|
||||||
},
|
|
||||||
PresenceCommand::IsConnected(responder) => {
|
|
||||||
let _ = responder.send(self.client.is_some());
|
|
||||||
}
|
|
||||||
PresenceCommand::Tick => {
|
|
||||||
if self.client.is_some() {
|
|
||||||
self.handle_update().await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = update_interval.tick() => {
|
|
||||||
let _ = PRESENCE_TX.send(PresenceCommand::Tick).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_connect(
|
|
||||||
&mut self,
|
|
||||||
responder: oneshot::Sender<bool>,
|
|
||||||
) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
|
|
||||||
Box::pin(async move {
|
|
||||||
if self.client.is_some() {
|
|
||||||
let _ = responder.send(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Actor: Connecting to Discord...");
|
|
||||||
let mut dc_client = DiscordIpcClient::new("1032772293220384808");
|
|
||||||
match dc_client.connect() {
|
|
||||||
Ok(()) => {
|
|
||||||
self.client = Some(dc_client);
|
|
||||||
println!("Actor: Connected successfully.");
|
|
||||||
self.handle_update().await;
|
|
||||||
let _ = responder.send(true);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!(
|
|
||||||
"Failed to connect to Discord: {:?}. Scheduling bounded retry...",
|
|
||||||
e
|
|
||||||
);
|
|
||||||
let tx = PRESENCE_TX.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
for attempt in 1..=3 {
|
|
||||||
tokio::time::sleep(Duration::from_secs(5 * attempt)).await;
|
|
||||||
let (resp_tx, rx) = oneshot::channel();
|
|
||||||
if tx.send(PresenceCommand::Connect(resp_tx)).await.is_ok() {
|
|
||||||
if rx.await.unwrap_or(false) {
|
|
||||||
println!("Actor: Reconnection attempt {} succeeded", attempt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"Actor: Reconnection attempt {} failed, retrying...",
|
|
||||||
attempt
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if !responder.is_closed() {
|
|
||||||
let _ = responder.send(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_disconnect(&mut self, responder: oneshot::Sender<()>) {
|
|
||||||
if let Some(mut client) = self.client.take() {
|
|
||||||
println!("Actor: Disconnecting from Discord...");
|
|
||||||
let _ = client.clear_activity();
|
|
||||||
let _ = client.close();
|
|
||||||
println!("Actor: Disconnected successfully.");
|
|
||||||
}
|
|
||||||
let _ = responder.send(());
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handle_update(&mut self) {
|
|
||||||
if let Some(client) = self.client.as_mut() {
|
|
||||||
let mut assets = Assets::new()
|
|
||||||
.large_image(&self.data.large_image_key)
|
|
||||||
.large_text(&self.data.large_image_text);
|
|
||||||
|
|
||||||
if let Some(key) = &self.data.small_image_key {
|
|
||||||
assets = assets.small_image(key);
|
|
||||||
}
|
|
||||||
if let Some(text) = &self.data.small_image_text {
|
|
||||||
assets = assets.small_text(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
let activity = Activity::new()
|
|
||||||
.state(&self.data.state)
|
|
||||||
.details(&self.data.details)
|
|
||||||
.timestamps(Timestamps::new().start(self.start_timestamp))
|
|
||||||
.assets(assets)
|
|
||||||
.buttons(vec![
|
|
||||||
Button::new(
|
|
||||||
"Download the Launcher",
|
|
||||||
"https://git.ez-pp.farm/EZPPFarm/EZPPLauncher/releases/latest",
|
|
||||||
),
|
|
||||||
Button::new("Join EZPPFarm", "https://ez-pp.farm/discord"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if let Err(e) = client.set_activity(activity) {
|
|
||||||
eprintln!("Failed to set activity, disconnecting: {:?}", e);
|
|
||||||
self.client = None;
|
|
||||||
|
|
||||||
// Don't await reconnection here - send command to avoid blocking the actor
|
|
||||||
let tx = PRESENCE_TX.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
||||||
let (resp_tx, _) = oneshot::channel();
|
|
||||||
let _ = tx.send(PresenceCommand::Connect(resp_tx)).await;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
println!("Actor: Presence updated successfully.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRESENCE_TX: Lazy<mpsc::Sender<PresenceCommand>> = Lazy::new(|| {
|
|
||||||
let (tx, rx) = mpsc::channel(10);
|
|
||||||
let mut actor = PresenceActor::new(rx);
|
|
||||||
tokio::spawn(async move { actor.run().await });
|
|
||||||
tx
|
|
||||||
});
|
|
||||||
|
|
||||||
pub static PRESENCE_DATA: Lazy<StdMutex<PresenceData>> = Lazy::new(|| {
|
|
||||||
StdMutex::new(PresenceData {
|
|
||||||
state: "Idle in Launcher...".to_string(),
|
|
||||||
details: " ".to_string(),
|
|
||||||
large_image_key: "ezppfarm".to_string(),
|
|
||||||
large_image_text: "EZPPFarm".to_string(),
|
|
||||||
small_image_key: None,
|
|
||||||
small_image_text: None,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
pub async fn connect() -> bool {
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
if PRESENCE_TX.send(PresenceCommand::Connect(tx)).await.is_ok() {
|
|
||||||
return rx.await.unwrap_or(false);
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn disconnect() {
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
// Use a timeout to ensure we don't hang the exit process if Discord is unresponsive
|
|
||||||
if let Ok(_) = PRESENCE_TX.send(PresenceCommand::Disconnect(tx)).await {
|
|
||||||
let _ = tokio::time::timeout(Duration::from_secs(2), rx).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn has_presence() -> bool {
|
|
||||||
let (tx, rx) = oneshot::channel();
|
|
||||||
if PRESENCE_TX
|
|
||||||
.send(PresenceCommand::IsConnected(tx))
|
|
||||||
.await
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
return rx.await.unwrap_or(false);
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_status(state: Option<&str>, details: Option<&str>, large_image_key: Option<&str>) {
|
|
||||||
let mut data = PRESENCE_DATA.lock().unwrap();
|
|
||||||
if let Some(s) = state {
|
|
||||||
data.state = s.to_string();
|
|
||||||
}
|
|
||||||
if let Some(d) = details {
|
|
||||||
data.details = d.to_string();
|
|
||||||
}
|
|
||||||
if let Some(img) = large_image_key {
|
|
||||||
data.large_image_key = img.to_string();
|
|
||||||
}
|
|
||||||
let data_clone = data.clone();
|
|
||||||
let tx = PRESENCE_TX.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let _ = tx.send(PresenceCommand::UpdateData(data_clone)).await;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_user(username: Option<&str>, id: Option<&str>) {
|
|
||||||
let mut data = PRESENCE_DATA.lock().unwrap();
|
|
||||||
data.small_image_key = id.map(|id_str| format!("https://a.ez-pp.farm/{}", id_str));
|
|
||||||
data.small_image_text = username.map(|s| s.to_string());
|
|
||||||
let data_clone = data.clone();
|
|
||||||
let tx = PRESENCE_TX.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let _ = tx.send(PresenceCommand::UpdateData(data_clone)).await;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,388 +0,0 @@
|
|||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
use sysinfo::Pid;
|
|
||||||
|
|
||||||
pub fn check_folder_completeness<P: AsRef<Path>>(folder_path: P, required_files: &[&str]) -> f32 {
|
|
||||||
let mut found = 0;
|
|
||||||
for file in required_files {
|
|
||||||
let file_path = folder_path.as_ref().join(file);
|
|
||||||
if file_path.exists() {
|
|
||||||
found += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if required_files.is_empty() {
|
|
||||||
100.0
|
|
||||||
} else {
|
|
||||||
(found as f32 / required_files.len() as f32) * 100.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_osu_user_config<P: AsRef<Path>>(
|
|
||||||
osu_folder_path: P,
|
|
||||||
) -> Option<std::collections::HashMap<String, String>> {
|
|
||||||
if !osu_folder_path.as_ref().exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_user = std::env::var("USERNAME").unwrap_or_else(|_| "Admin".to_string());
|
|
||||||
let osu_config_path = osu_folder_path
|
|
||||||
.as_ref()
|
|
||||||
.join(format!("osu!.{}.cfg", current_user));
|
|
||||||
if !osu_config_path.exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut config_map = std::collections::HashMap::new();
|
|
||||||
if let Ok(contents) = std::fs::read_to_string(osu_config_path) {
|
|
||||||
for line in contents.lines() {
|
|
||||||
if let Some((key, value)) = line.split_once(" = ") {
|
|
||||||
config_map.insert(key.trim().to_string(), value.trim().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(config_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_osu_user_config_vals(
|
|
||||||
osu_folder_path: &str,
|
|
||||||
key_values: &[(&str, Option<&str>)],
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
let current_user = std::env::var("USERNAME").unwrap_or_else(|_| "Admin".to_string());
|
|
||||||
let osu_config_path = Path::new(osu_folder_path).join(format!("osu!.{}.cfg", current_user));
|
|
||||||
|
|
||||||
if !osu_config_path.exists() {
|
|
||||||
return Err("osu! user config file does not exist".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut lines = fs::read_to_string(&osu_config_path)
|
|
||||||
.map_err(|e| e.to_string())?
|
|
||||||
.lines()
|
|
||||||
.map(|line| line.to_string())
|
|
||||||
.collect::<Vec<String>>();
|
|
||||||
|
|
||||||
let mut keys_to_set: std::collections::HashMap<&str, &str> = std::collections::HashMap::new();
|
|
||||||
let mut keys_to_add: std::collections::HashSet<&str> = std::collections::HashSet::new();
|
|
||||||
|
|
||||||
for (key, value_opt) in key_values.iter() {
|
|
||||||
if let Some(value) = value_opt {
|
|
||||||
keys_to_set.insert(*key, *value);
|
|
||||||
keys_to_add.insert(*key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut updates = Vec::new();
|
|
||||||
for (i, line) in lines.iter().enumerate() {
|
|
||||||
if let Some((existing_key, _)) = line.split_once(" = ") {
|
|
||||||
let trimmed_key = existing_key.trim();
|
|
||||||
if let Some(new_value) = keys_to_set.get(trimmed_key) {
|
|
||||||
updates.push((i, trimmed_key.to_string(), new_value.to_string()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i, trimmed_key, new_value) in updates {
|
|
||||||
lines[i] = format!("{} = {}", trimmed_key, new_value);
|
|
||||||
keys_to_add.remove(trimmed_key.as_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
for key in keys_to_add {
|
|
||||||
if let Some(value) = keys_to_set.get(key) {
|
|
||||||
lines.push(format!("{} = {}", key, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_content = lines.join("\n") + "\n";
|
|
||||||
fs::write(&osu_config_path, new_content).map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_osu_config_vals(
|
|
||||||
osu_folder_path: &str,
|
|
||||||
key_values: &[(&str, Option<&str>)],
|
|
||||||
) -> Result<bool, String> {
|
|
||||||
let osu_config_path = Path::new(osu_folder_path).join("osu!.cfg");
|
|
||||||
|
|
||||||
if !osu_config_path.exists() {
|
|
||||||
return Err("osu!.cfg file does not exist".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut lines = fs::read_to_string(&osu_config_path)
|
|
||||||
.map_err(|e| e.to_string())?
|
|
||||||
.lines()
|
|
||||||
.map(|line| line.to_string())
|
|
||||||
.collect::<Vec<String>>();
|
|
||||||
|
|
||||||
let mut keys_to_set: std::collections::HashMap<&str, &str> = std::collections::HashMap::new();
|
|
||||||
let mut keys_to_add: std::collections::HashSet<&str> = std::collections::HashSet::new();
|
|
||||||
|
|
||||||
for (key, value_opt) in key_values.iter() {
|
|
||||||
if let Some(value) = value_opt {
|
|
||||||
keys_to_set.insert(*key, *value);
|
|
||||||
keys_to_add.insert(*key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut updates = Vec::new();
|
|
||||||
for (i, line) in lines.iter().enumerate() {
|
|
||||||
if let Some((existing_key, _)) = line.split_once(" = ") {
|
|
||||||
let trimmed_key = existing_key.trim();
|
|
||||||
if let Some(new_value) = keys_to_set.get(trimmed_key) {
|
|
||||||
updates.push((i, trimmed_key.to_string(), new_value.to_string()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i, trimmed_key, new_value) in updates {
|
|
||||||
lines[i] = format!("{} = {}", trimmed_key, new_value);
|
|
||||||
keys_to_add.remove(trimmed_key.as_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
for key in keys_to_add {
|
|
||||||
if let Some(value) = keys_to_set.get(key) {
|
|
||||||
lines.push(format!("{} = {}", key, value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_content = lines.join("\n") + "\n";
|
|
||||||
fs::write(&osu_config_path, new_content).map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_osu_config<P: AsRef<Path>>(
|
|
||||||
osu_folder_path: P,
|
|
||||||
) -> Option<std::collections::HashMap<String, String>> {
|
|
||||||
if !osu_folder_path.as_ref().exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let osu_config_path = osu_folder_path.as_ref().join("osu!.cfg");
|
|
||||||
if !osu_config_path.exists() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut config_map = std::collections::HashMap::new();
|
|
||||||
if let Ok(contents) = std::fs::read_to_string(osu_config_path) {
|
|
||||||
for line in contents.lines() {
|
|
||||||
if let Some((key, value)) = line.split_once(" = ") {
|
|
||||||
config_map.insert(key.trim().to_string(), value.trim().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(config_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn is_osuwinello_available() -> bool {
|
|
||||||
use std::process::Command;
|
|
||||||
Command::new("osu-wine")
|
|
||||||
.arg("--info")
|
|
||||||
.stdout(std::process::Stdio::null())
|
|
||||||
.stderr(std::process::Stdio::null())
|
|
||||||
.status()
|
|
||||||
.is_ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub fn is_osuwinello_available() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn is_wmctrl_available() -> bool {
|
|
||||||
use std::process::Command;
|
|
||||||
Command::new("wmctrl")
|
|
||||||
.arg("-V")
|
|
||||||
.stdout(std::process::Stdio::null())
|
|
||||||
.stderr(std::process::Stdio::null())
|
|
||||||
.status()
|
|
||||||
.is_ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub fn is_wmctrl_available() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn get_window_title_by_pid(target_pid: Pid) -> String {
|
|
||||||
use std::process::Command;
|
|
||||||
let find_title = || -> Option<String> {
|
|
||||||
let output = Command::new("wmctrl").arg("-lp").output().ok()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let output_str = String::from_utf8(output.stdout).ok()?;
|
|
||||||
|
|
||||||
for line in output_str.lines() {
|
|
||||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
|
||||||
if parts.len() < 4 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(pid) = parts[2].parse::<u32>() {
|
|
||||||
if pid == target_pid.as_u32() {
|
|
||||||
let title = parts[4..].join(" ");
|
|
||||||
return Some(title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
find_title().unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub fn get_window_title_by_pid(pid: Pid) -> String {
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::os::windows::ffi::OsStringExt;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use winapi::shared::windef::HWND;
|
|
||||||
use winapi::um::winuser::{
|
|
||||||
EnumWindows, GetWindowTextW, GetWindowThreadProcessId, IsWindowVisible,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "system" fn enum_windows_proc(
|
|
||||||
hwnd: HWND,
|
|
||||||
lparam: winapi::shared::minwindef::LPARAM,
|
|
||||||
) -> i32 {
|
|
||||||
unsafe {
|
|
||||||
let data = &mut *(lparam as *mut (u32, Arc<Mutex<Option<String>>>));
|
|
||||||
let target_pid = data.0;
|
|
||||||
let result = &data.1;
|
|
||||||
|
|
||||||
let mut window_pid = 0u32;
|
|
||||||
GetWindowThreadProcessId(hwnd, &mut window_pid);
|
|
||||||
if window_pid == target_pid && IsWindowVisible(hwnd) != 0 {
|
|
||||||
let mut title = vec![0u16; 512];
|
|
||||||
let length = GetWindowTextW(hwnd, title.as_mut_ptr(), title.len() as i32);
|
|
||||||
if length > 0 {
|
|
||||||
let title = OsString::from_wide(&title[..length as usize]);
|
|
||||||
let title_str = title.to_string_lossy().into_owned();
|
|
||||||
if !title_str.is_empty() {
|
|
||||||
*result.lock().unwrap() = Some(title_str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = Arc::new(Mutex::new(None));
|
|
||||||
let mut data = (pid.as_u32(), Arc::clone(&result));
|
|
||||||
unsafe {
|
|
||||||
EnumWindows(
|
|
||||||
Some(enum_windows_proc),
|
|
||||||
&mut data as *mut _ as winapi::shared::minwindef::LPARAM,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
result.lock().unwrap().clone().unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn is_net8_installed() -> bool {
|
|
||||||
use tokio::process::Command;
|
|
||||||
|
|
||||||
let mut command = Command::new("dotnet");
|
|
||||||
command.arg("--list-runtimes");
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
|
||||||
command.creation_flags(CREATE_NO_WINDOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
let output_result = command.output().await;
|
|
||||||
match output_result {
|
|
||||||
Ok(output) => {
|
|
||||||
if !output.status.success() {
|
|
||||||
eprintln!(
|
|
||||||
"Error: `dotnet --list-runtimes` failed with status: {}",
|
|
||||||
output.status
|
|
||||||
);
|
|
||||||
eprintln!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let stdout_str = String::from_utf8_lossy(&output.stdout);
|
|
||||||
stdout_str.lines().any(|line| line.starts_with("Microsoft.WindowsDesktop.App 8."))
|
|
||||||
}
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn encrypt_password(password: &str, _entropy: &str) -> Result<String, String> {
|
|
||||||
Ok(password.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub fn encrypt_password(password: &str, entropy: &str) -> Result<String, String> {
|
|
||||||
use base64::{Engine as _, engine::general_purpose};
|
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::os::windows::ffi::OsStrExt;
|
|
||||||
use std::ptr;
|
|
||||||
use std::slice;
|
|
||||||
use winapi::shared::minwindef::{BYTE, DWORD, LPVOID};
|
|
||||||
use winapi::shared::ntdef::LPCWSTR;
|
|
||||||
use winapi::um::dpapi::{CRYPTPROTECT_UI_FORBIDDEN, CryptProtectData};
|
|
||||||
use winapi::um::winbase::LocalFree;
|
|
||||||
use winapi::um::wincrypt::DATA_BLOB;
|
|
||||||
|
|
||||||
let description = "Encrypted";
|
|
||||||
|
|
||||||
let password_bytes = password.as_bytes();
|
|
||||||
let mut input_blob = DATA_BLOB {
|
|
||||||
cbData: password_bytes.len() as DWORD,
|
|
||||||
pbData: password_bytes.as_ptr() as *mut BYTE,
|
|
||||||
};
|
|
||||||
|
|
||||||
let entropy_bytes = entropy.as_bytes();
|
|
||||||
let mut entropy_blob = DATA_BLOB {
|
|
||||||
cbData: entropy_bytes.len() as DWORD,
|
|
||||||
pbData: entropy_bytes.as_ptr() as *mut BYTE,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut output_blob = DATA_BLOB {
|
|
||||||
cbData: 0,
|
|
||||||
pbData: ptr::null_mut(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let wide_description: Vec<u16> = OsStrExt::encode_wide(OsStr::new(description))
|
|
||||||
.chain(Some(0))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let p_description: LPCWSTR = wide_description.as_ptr();
|
|
||||||
|
|
||||||
let result = unsafe {
|
|
||||||
CryptProtectData(
|
|
||||||
&mut input_blob,
|
|
||||||
p_description,
|
|
||||||
&mut entropy_blob,
|
|
||||||
ptr::null_mut(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
CRYPTPROTECT_UI_FORBIDDEN,
|
|
||||||
&mut output_blob,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if result == 0 {
|
|
||||||
return Err("CryptProtectData failed".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let encrypted_data =
|
|
||||||
unsafe { slice::from_raw_parts(output_blob.pbData, output_blob.cbData as usize).to_vec() };
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
LocalFree(output_blob.pbData as LPVOID);
|
|
||||||
}
|
|
||||||
|
|
||||||
let base64_string = general_purpose::STANDARD.encode(&encrypted_data);
|
|
||||||
|
|
||||||
Ok(base64_string)
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
|
||||||
"productName": "EZPPLauncher",
|
|
||||||
"version": "3.2.0",
|
|
||||||
"identifier": "farm.EZPPFarm.Launcher",
|
|
||||||
"mainBinaryName": "ezpplauncher",
|
|
||||||
"build": {
|
|
||||||
"beforeDevCommand": "bun run vite:dev",
|
|
||||||
"devUrl": "http://localhost:1420",
|
|
||||||
"beforeBuildCommand": "",
|
|
||||||
"frontendDist": "../build"
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
"windows": [
|
|
||||||
{
|
|
||||||
"title": "EZPPLauncher",
|
|
||||||
"width": 1000,
|
|
||||||
"height": 650,
|
|
||||||
"decorations": false,
|
|
||||||
"resizable": false,
|
|
||||||
"maximizable": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"withGlobalTauri": true,
|
|
||||||
"security": {
|
|
||||||
"csp": null,
|
|
||||||
"assetProtocol": {
|
|
||||||
"enable": true,
|
|
||||||
"scope": [
|
|
||||||
"$HOME/.ezpplauncher/themes/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bundle": {
|
|
||||||
"publisher": "EZPPFarm",
|
|
||||||
"copyright": "EZPPFarm",
|
|
||||||
"homepage": "https://ez-pp.farm",
|
|
||||||
"license": "GPL-3.0",
|
|
||||||
"active": true,
|
|
||||||
"targets": [
|
|
||||||
"nsis",
|
|
||||||
"appimage"
|
|
||||||
],
|
|
||||||
"windows": {
|
|
||||||
"webviewInstallMode": {
|
|
||||||
"silent": true,
|
|
||||||
"type": "downloadBootstrapper"
|
|
||||||
},
|
|
||||||
"nsis": {
|
|
||||||
"installMode": "currentUser",
|
|
||||||
"compression": "lzma",
|
|
||||||
"installerIcon": "icons/icon.ico",
|
|
||||||
"installerHooks": "./nsis/nsis-hooks.nsh"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"icon": [
|
|
||||||
"icons/32x32.png",
|
|
||||||
"icons/128x128.png",
|
|
||||||
"icons/128x128@2x.png",
|
|
||||||
"icons/icon.icns",
|
|
||||||
"icons/icon.ico"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
@import "tw-animate-css";
|
|
||||||
|
|
||||||
@custom-variant dark (&:where(.dark, .dark *));
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--radius: 0.625rem;
|
|
||||||
--background: oklch(95.36% 0.017 256.57);
|
|
||||||
--foreground: oklch(40.06% 0.038 266.38);
|
|
||||||
--card: oklch(100% 0 0);
|
|
||||||
--card-foreground: oklch(40.06% 0.038 266.38);
|
|
||||||
--popover: oklch(84.01% 0.028 258.47);
|
|
||||||
--popover-foreground: oklch(40.06% 0.038 266.38);
|
|
||||||
--primary: oklch(60.7% 0.226 299.68);
|
|
||||||
--primary-foreground: oklch(100% 0 0);
|
|
||||||
--secondary: oklch(84.01% 0.028 258.47);
|
|
||||||
--secondary-foreground: oklch(40.06% 0.038 266.38);
|
|
||||||
--muted: oklch(89.49% 0.023 256.59);
|
|
||||||
--muted-foreground: oklch(51.01% 0.028 265.36);
|
|
||||||
--accent: oklch(54.41% 0.186 230.5);
|
|
||||||
--accent-foreground: oklch(100% 0 0);
|
|
||||||
--destructive: oklch(51.68% 0.202 15.84);
|
|
||||||
--destructive-foreground: oklch(100% 0 0);
|
|
||||||
--border: oklch(78.52% 0.026 260.1);
|
|
||||||
--input: oklch(84.01% 0.028 258.47);
|
|
||||||
--ring: oklch(60.7% 0.226 299.68);
|
|
||||||
--chart-1: oklch(60.7% 0.226 299.68);
|
|
||||||
--chart-2: oklch(54.41% 0.186 230.5);
|
|
||||||
--chart-3: oklch(46.49% 0.139 139.66);
|
|
||||||
--chart-4: oklch(60.01% 0.202 55.86);
|
|
||||||
--chart-5: oklch(70.11% 0.125 39.15);
|
|
||||||
--sidebar: oklch(92.65% 0.019 256.57);
|
|
||||||
--sidebar-background: oklch(92.65% 0.019 256.57);
|
|
||||||
--sidebar-foreground: oklch(40.06% 0.038 266.38);
|
|
||||||
--sidebar-primary: oklch(60.7% 0.226 299.68);
|
|
||||||
--sidebar-primary-foreground: oklch(100% 0 0);
|
|
||||||
--sidebar-accent: oklch(54.41% 0.186 230.5);
|
|
||||||
--sidebar-accent-foreground: oklch(100% 0 0);
|
|
||||||
--sidebar-border: oklch(78.52% 0.026 260.1);
|
|
||||||
--sidebar-ring: oklch(60.7% 0.226 299.68);
|
|
||||||
|
|
||||||
--font-sans:
|
|
||||||
"Sora", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
||||||
"Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
--font-mono:
|
|
||||||
"Space Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
||||||
"Courier New", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
--background: oklch(17.02% 0.042 282.86);
|
|
||||||
--foreground: oklch(89.24% 0.079 263.24);
|
|
||||||
--card: oklch(20.22% 0.048 282.86);
|
|
||||||
--card-foreground: oklch(89.24% 0.079 263.24);
|
|
||||||
--popover: oklch(20.3% 0.05 282.86);
|
|
||||||
--popover-foreground: oklch(89.24% 0.079 263.24);
|
|
||||||
--primary: oklch(72.08% 0.196 356.34);
|
|
||||||
--primary-foreground: oklch(20.22% 0.048 282.86);
|
|
||||||
--secondary: oklch(42.99% 0.031 270.49);
|
|
||||||
--secondary-foreground: oklch(89.24% 0.079 263.24);
|
|
||||||
--muted: oklch(24.41% 0.048 271.21);
|
|
||||||
--muted-foreground: oklch(73.83% 0.057 265.65);
|
|
||||||
--accent: oklch(86.2% 0.131 300.42);
|
|
||||||
--accent-foreground: oklch(20.22% 0.048 282.86);
|
|
||||||
--destructive: oklch(77.23% 0.146 11.66);
|
|
||||||
--destructive-foreground: oklch(20.22% 0.048 282.86);
|
|
||||||
--border: oklch(27.7% 0.041 276.87);
|
|
||||||
--input: oklch(27.7% 0.041 276.87);
|
|
||||||
--ring: oklch(72.08% 0.196 356.34);
|
|
||||||
--chart-1: oklch(72.08% 0.196 356.34);
|
|
||||||
--chart-2: oklch(77.19% 0.121 223.01);
|
|
||||||
--chart-3: oklch(79.1% 0.119 150.21);
|
|
||||||
--chart-4: oklch(79.74% 0.167 57.97);
|
|
||||||
--chart-5: oklch(92.11% 0.061 37.8);
|
|
||||||
--sidebar: oklch(13.29% 0.036 282.86);
|
|
||||||
--sidebar-background: oklch(13.29% 0.036 282.86);
|
|
||||||
--sidebar-foreground: oklch(89.24% 0.079 263.24);
|
|
||||||
--sidebar-primary: oklch(72.08% 0.196 356.34);
|
|
||||||
--sidebar-primary-foreground: oklch(20.22% 0.048 282.86);
|
|
||||||
--sidebar-accent: oklch(75.21% 0.121 293.01);
|
|
||||||
--sidebar-accent-foreground: oklch(20.22% 0.048 282.86);
|
|
||||||
--sidebar-border: oklch(35.13% 0.03 273.31);
|
|
||||||
--sidebar-ring: oklch(72.08% 0.196 356.34);
|
|
||||||
}
|
|
||||||
|
|
||||||
@theme inline {
|
|
||||||
--radius-sm: calc(var(--radius) - 4px);
|
|
||||||
--radius-md: calc(var(--radius) - 2px);
|
|
||||||
--radius-lg: var(--radius);
|
|
||||||
--radius-xl: calc(var(--radius) + 4px);
|
|
||||||
--color-background: var(--background);
|
|
||||||
--color-theme: #181825;
|
|
||||||
--color-theme-50: #e9e9f1;
|
|
||||||
--color-theme-100: #dbdbe8;
|
|
||||||
--color-theme-200: #bfbfd6;
|
|
||||||
--color-theme-300: #a4a4c4;
|
|
||||||
--color-theme-400: #8888b2;
|
|
||||||
--color-theme-500: #6c6ca0;
|
|
||||||
--color-theme-600: #575786;
|
|
||||||
--color-theme-700: #45456b;
|
|
||||||
--color-theme-800: #33334f;
|
|
||||||
--color-theme-900: #212133;
|
|
||||||
--color-theme-950: #181825;
|
|
||||||
--color-foreground: var(--foreground);
|
|
||||||
--color-card: var(--card);
|
|
||||||
--color-card-foreground: var(--card-foreground);
|
|
||||||
--color-popover: var(--popover);
|
|
||||||
--color-popover-foreground: var(--popover-foreground);
|
|
||||||
--color-primary: var(--primary);
|
|
||||||
--color-primary-50: #ffe5f1;
|
|
||||||
--color-primary-100: #ffcce2;
|
|
||||||
--color-primary-200: #ff99c5;
|
|
||||||
--color-primary-300: #ff66a8;
|
|
||||||
--color-primary-400: #ff338b;
|
|
||||||
--color-primary-500: #ff006e;
|
|
||||||
--color-primary-600: #cc0058;
|
|
||||||
--color-primary-700: #990042;
|
|
||||||
--color-primary-800: #66002c;
|
|
||||||
--color-primary-900: #330016;
|
|
||||||
--color-primary-950: #24000f;
|
|
||||||
--color-primary-foreground: var(--primary-foreground);
|
|
||||||
--color-secondary: var(--secondary);
|
|
||||||
--color-secondary-foreground: var(--secondary-foreground);
|
|
||||||
--color-muted: var(--muted);
|
|
||||||
--color-muted-foreground: var(--muted-foreground);
|
|
||||||
--color-accent: var(--accent);
|
|
||||||
--color-accent-foreground: var(--accent-foreground);
|
|
||||||
--color-destructive: var(--destructive);
|
|
||||||
--color-border: var(--border);
|
|
||||||
--color-input: var(--input);
|
|
||||||
--color-ring: var(--ring);
|
|
||||||
--color-chart-1: var(--chart-1);
|
|
||||||
--color-chart-2: var(--chart-2);
|
|
||||||
--color-chart-3: var(--chart-3);
|
|
||||||
--color-chart-4: var(--chart-4);
|
|
||||||
--color-chart-5: var(--chart-5);
|
|
||||||
--color-sidebar: var(--sidebar);
|
|
||||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
||||||
--color-sidebar-primary: var(--sidebar-primary);
|
|
||||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
||||||
--color-sidebar-accent: var(--sidebar-accent);
|
|
||||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
||||||
--color-sidebar-border: var(--sidebar-border);
|
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
main[data-theme="execution_clap"] {
|
|
||||||
--primary: #fc112b;
|
|
||||||
--primary-foreground: #fff;
|
|
||||||
--ring: #fc112b;
|
|
||||||
--color-primary-50: #fef2f2;
|
|
||||||
--color-primary-100: #fee2e2;
|
|
||||||
--color-primary-200: #fecaca;
|
|
||||||
--color-primary-300: #fca5a5;
|
|
||||||
--color-primary-400: #f87171;
|
|
||||||
--color-primary-500: #ef4444;
|
|
||||||
--color-primary-600: #dc2626;
|
|
||||||
--color-primary-700: #b91c1c;
|
|
||||||
--color-primary-800: #991b1b;
|
|
||||||
--color-primary-900: #7f1d1d;
|
|
||||||
--color-primary-950: #450a0a;
|
|
||||||
--bg-primary-50: #fef2f2;
|
|
||||||
--bg-primary-100: #fee2e2;
|
|
||||||
--bg-primary-200: #fecaca;
|
|
||||||
--bg-primary-300: #fca5a5;
|
|
||||||
--bg-primary-400: #f87171;
|
|
||||||
--bg-primary-500: #ef4444;
|
|
||||||
--bg-primary-600: #dc2626;
|
|
||||||
--bg-primary-700: #b91c1c;
|
|
||||||
--bg-primary-800: #991b1b;
|
|
||||||
--bg-primary-900: #7f1d1d;
|
|
||||||
--bg-primary-950: #450a0a;
|
|
||||||
}
|
|
||||||
|
|
||||||
main[data-theme="lost_umbrella"] {
|
|
||||||
--primary: #e5e5e5;
|
|
||||||
--primary-foreground: #000;
|
|
||||||
--ring: #e5e5e5;
|
|
||||||
--color-primary-50: #0d0d0d;
|
|
||||||
--color-primary-100: #1a1a1a;
|
|
||||||
--color-primary-200: #333333;
|
|
||||||
--color-primary-300: #4d4d4d;
|
|
||||||
--color-primary-400: #666666;
|
|
||||||
--color-primary-500: #808080;
|
|
||||||
--color-primary-600: #999999;
|
|
||||||
--color-primary-700: #b3b3b3;
|
|
||||||
--color-primary-800: #cccccc;
|
|
||||||
--color-primary-900: #e6e6e6;
|
|
||||||
--color-primary-950: #f2f2f2;
|
|
||||||
--bg-primary-50: #0d0d0d;
|
|
||||||
--bg-primary-100: #1a1a1a;
|
|
||||||
--bg-primary-200: #333333;
|
|
||||||
--bg-primary-300: #4d4d4d;
|
|
||||||
--bg-primary-400: #666666;
|
|
||||||
--bg-primary-500: #808080;
|
|
||||||
--bg-primary-600: #999999;
|
|
||||||
--bg-primary-700: #b3b3b3;
|
|
||||||
--bg-primary-800: #cccccc;
|
|
||||||
--bg-primary-900: #e6e6e6;
|
|
||||||
--bg-primary-950: #f2f2f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
|
||||||
* {
|
|
||||||
@apply border-border outline-ring/50;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
@apply bg-background text-foreground;
|
|
||||||
}
|
|
||||||
button:not([disabled]),
|
|
||||||
[role="button"]:not([disabled]) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en" class="dark">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<title>EZPPLauncher</title>
|
|
||||||
%sveltekit.head%
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="bg-theme-950" data-sveltekit-preload-data="hover">
|
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 173 KiB |
@@ -1,92 +0,0 @@
|
|||||||
import type {
|
|
||||||
EZPPUser,
|
|
||||||
EZPPUserInfoResponse,
|
|
||||||
EZPPUserResponse,
|
|
||||||
EZPPUSerStatusResponse,
|
|
||||||
} from '@/types';
|
|
||||||
import { betterFetch } from '@better-fetch/fetch';
|
|
||||||
|
|
||||||
const BANCHO_ENDPOINT = 'https://c.ez-pp.farm/';
|
|
||||||
const API_ENDPOINT = 'https://api.ez-pp.farm/';
|
|
||||||
const ENDPOINT = 'https://ez-pp.farm/';
|
|
||||||
|
|
||||||
const timeout = 5000; // 5 seconds;
|
|
||||||
|
|
||||||
export const ezppfarm = {
|
|
||||||
ping: async (): Promise<number | undefined> => {
|
|
||||||
try {
|
|
||||||
const start = Date.now();
|
|
||||||
const request = await betterFetch(BANCHO_ENDPOINT, {
|
|
||||||
timeout,
|
|
||||||
headers: {
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (request.error) return undefined;
|
|
||||||
const ping = Date.now() - start;
|
|
||||||
return ping;
|
|
||||||
} catch {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
login: async (
|
|
||||||
username: string,
|
|
||||||
password: string
|
|
||||||
): Promise<
|
|
||||||
| {
|
|
||||||
code: number;
|
|
||||||
message: string;
|
|
||||||
user?: EZPPUser;
|
|
||||||
}
|
|
||||||
| undefined
|
|
||||||
> => {
|
|
||||||
const request = await betterFetch<EZPPUserResponse>(`${ENDPOINT}login/check`, {
|
|
||||||
method: 'POST',
|
|
||||||
timeout,
|
|
||||||
body: JSON.stringify({
|
|
||||||
username: username,
|
|
||||||
password: password,
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (request.error) {
|
|
||||||
if (request.error.status >= 500 && request.error.status < 600)
|
|
||||||
throw new Error('Server not reachable');
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return request.data;
|
|
||||||
},
|
|
||||||
getUserInfo: async (userId: number, scope: 'all' | 'info' | 'stats' = 'all') => {
|
|
||||||
const request = await betterFetch<EZPPUserInfoResponse>(`${API_ENDPOINT}v1/get_player_info`, {
|
|
||||||
timeout,
|
|
||||||
query: {
|
|
||||||
id: userId,
|
|
||||||
scope,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return request.error ? undefined : request.data;
|
|
||||||
},
|
|
||||||
getUserStatus: async (userId: number) => {
|
|
||||||
const request = await betterFetch<EZPPUSerStatusResponse>(
|
|
||||||
`${API_ENDPOINT}v1/get_player_status`,
|
|
||||||
{
|
|
||||||
timeout,
|
|
||||||
query: {
|
|
||||||
id: userId,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return request.error ? undefined : request.data;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import type { Release } from '@/types';
|
|
||||||
import { betterFetch } from '@better-fetch/fetch';
|
|
||||||
import semver from 'semver';
|
|
||||||
|
|
||||||
const ENDPOINT = 'https://git.ez-pp.farm/';
|
|
||||||
|
|
||||||
const timeout = 5000; // 5 seconds;
|
|
||||||
|
|
||||||
export const git = {
|
|
||||||
hasUpdate: async (version: string): Promise<Release | undefined> => {
|
|
||||||
try {
|
|
||||||
const request = await betterFetch<Release[]>(
|
|
||||||
`${ENDPOINT}api/v1/repos/EZPPFarm/EZPPLauncher/releases?limit=1`,
|
|
||||||
{
|
|
||||||
timeout,
|
|
||||||
headers: {
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (request.error) return undefined;
|
|
||||||
|
|
||||||
const latestRelease = request.data[0];
|
|
||||||
if (!latestRelease) return undefined;
|
|
||||||
|
|
||||||
const hasUpdate = semver.lt(version, latestRelease.tag_name);
|
|
||||||
|
|
||||||
return hasUpdate ? latestRelease : undefined;
|
|
||||||
} catch {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import type { StreamsResult } from '@/types';
|
|
||||||
import { betterFetch } from '@better-fetch/fetch';
|
|
||||||
|
|
||||||
const API_ENDPOINT = 'https://osu.ppy.sh/api/';
|
|
||||||
|
|
||||||
const timeout = 5000; // 5 seconds;
|
|
||||||
|
|
||||||
export const osuapi = {
|
|
||||||
latestBuildVersion: async (releaseStream: string): Promise<string | undefined> => {
|
|
||||||
const request = await betterFetch<StreamsResult>(`${API_ENDPOINT}v2/changelog`, {
|
|
||||||
timeout,
|
|
||||||
query: {
|
|
||||||
stream: 'none',
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'User-Agent': 'EZPPLauncher',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (request.error) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const releaseData = request.data;
|
|
||||||
if (!releaseData || !releaseData.streams) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (releaseData.streams.length === 0) return undefined;
|
|
||||||
const selectedRelease = releaseData.streams.find(
|
|
||||||
(releaseBuild) =>
|
|
||||||
releaseBuild.name.toLowerCase() === releaseStream.replaceAll(' ', '').toLowerCase()
|
|
||||||
);
|
|
||||||
if (!selectedRelease) return undefined;
|
|
||||||
return selectedRelease.latest_build.display_version;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
const API_ENDPOINT = 'https://osu.direct/api/';
|
|
||||||
|
|
||||||
export const osudirect = {
|
|
||||||
osu: async (mapId: number): Promise<string | undefined> => {
|
|
||||||
try {
|
|
||||||
return await (await fetch(API_ENDPOINT + `osu/${mapId}?raw`)).text();
|
|
||||||
} catch {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
|
||||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
...restProps
|
|
||||||
}: AlertDialogPrimitive.ActionProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<AlertDialogPrimitive.Action bind:ref class={cn(buttonVariants(), className)} {...restProps} />
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
|
||||||
import { buttonVariants } from '$lib/components/ui/button/index.js';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
...restProps
|
|
||||||
}: AlertDialogPrimitive.CancelProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<AlertDialogPrimitive.Cancel
|
|
||||||
bind:ref
|
|
||||||
class={cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { AlertDialog as AlertDialogPrimitive, type WithoutChild } from 'bits-ui';
|
|
||||||
import AlertDialogOverlay from './alert-dialog-overlay.svelte';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
portalProps,
|
|
||||||
...restProps
|
|
||||||
}: WithoutChild<AlertDialogPrimitive.ContentProps> & {
|
|
||||||
portalProps?: AlertDialogPrimitive.PortalProps;
|
|
||||||
} = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<AlertDialogPrimitive.Portal {...portalProps}>
|
|
||||||
<AlertDialogOverlay />
|
|
||||||
<AlertDialogPrimitive.Content
|
|
||||||
bind:ref
|
|
||||||
class={cn(
|
|
||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
</AlertDialogPrimitive.Portal>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { AlertDialog as AlertDialogPrimitive } from 'bits-ui';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
...restProps
|
|
||||||
}: AlertDialogPrimitive.DescriptionProps = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<AlertDialogPrimitive.Description
|
|
||||||
bind:ref
|
|
||||||
class={cn('text-muted-foreground text-sm', className)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { WithElementRef } from 'bits-ui';
|
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={ref}
|
|
||||||
class={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
|
|
||||||
{...restProps}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { WithElementRef } from 'bits-ui';
|
|
||||||
import type { HTMLAttributes } from 'svelte/elements';
|
|
||||||
import { cn } from '$lib/utils.js';
|
|
||||||
|
|
||||||
let {
|
|
||||||
ref = $bindable(null),
|
|
||||||
class: className,
|
|
||||||
children,
|
|
||||||
...restProps
|
|
||||||
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={ref}
|
|
||||||
class={cn('flex flex-col space-y-2 text-center sm:text-left', className)}
|
|
||||||
{...restProps}
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||