diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..722a0f6
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,35 @@
+name: "Validate & Build"
+
+on:
+ workflow_call:
+
+jobs:
+ Sanity:
+ name: Build
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm 📥
+ uses: pnpm/action-setup@v4
+ with:
+ version: latest
+
+ - name: Install Node.js 📥
+ uses: actions/setup-node@v4
+ with:
+ cache: pnpm
+ node-version: latest
+
+ - name: Install dependencies 📥
+ run: pnpm install
+
+ - name: Build
+ run: pnpm run build
+
+ - name: Upload Build Artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: luna-artifacts
+ path: ./dist
diff --git a/.github/workflows/releaseMaster.yml b/.github/workflows/releaseMaster.yml
new file mode 100644
index 0000000..cb7529f
--- /dev/null
+++ b/.github/workflows/releaseMaster.yml
@@ -0,0 +1,32 @@
+name: "[master] Release"
+
+on:
+ push:
+ paths-ignore:
+ - "**/*.md"
+ - ".vscode/**"
+
+jobs:
+ Build:
+ uses: ./.github/workflows/build.yml
+
+ Release:
+ name: Release latest on GitHub
+ needs: Build
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Download All Artifacts
+ uses: actions/download-artifact@v4
+ with:
+ name: luna-artifacts
+ path: ./dist/
+
+ - name: Publish latest release on GitHub
+ uses: marvinpinto/action-automatic-releases@latest
+ with:
+ repo_token: ${{ secrets.GITHUB_TOKEN }}
+ automatic_release_tag: latest
+ prerelease: false
+ title: Latest Release
+ files: ./dist/**
diff --git a/.gitignore b/.gitignore
index a9e3938..1cc8631 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,140 +1,6 @@
-### Node ###
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-### Node Patch ###
-# Serverless Webpack directories
-.webpack/
-
-# Optional stylelint cache
-
-# SvelteKit build / generate output
-.svelte-kit
-
-# End of https://www.toptal.com/developers/gitignore/api/node
\ No newline at end of file
+dist/
+dist/itzzexcel.oled-theme.json
+dist/itzzexcel.oled-theme.mjs
+dist/itzzexcel.oled-theme.mjs.map
+dist/store.json
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index f288702..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- 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)
-
- 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 .
-
-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:
-
- Copyright (C)
- 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
-.
-
- 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
-.
diff --git a/README.md b/README.md
index f301fc5..fd3dd4d 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,26 @@
-# Excel's Neptune Projects
+# OLED Theme Luna Plugin
-This repository a repository containing my Neptune (TIDAL Modded Client) projects.
+This is a port of the OLED Theme plugin from Neptune to Luna framework.
-
+## Description
-### Credits to [Inrixia](https://github.com/inrixia) for some of the libraries/files used in this repository.
-- tracer.js (tracer.ts)
-- Get the cover URL method
-
+A working theme plugin that applies a dark OLED-friendly theme to Tidal Luna.
-## Index:
-- [Copy Lyrics](#copy-lyrics)
-- [OLED Theme](#oled-theme)
+## Features
+- Applies a dark, OLED-optimized theme
+- Fetches the latest theme CSS from the GitHub repository
-### Copy Lyrics
-**(load it as a PLUGIN)**
-A plugin that allows the user copy the lyrics only selecting it.
-```
-https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/plugins/plugins/copy-lyrics/dist/
-```
-https://github.com/user-attachments/assets/02fe7e28-94ee-4f90-a7e6-223044d680b5
-
+## Installation
-### OLED Theme
-**(load it as a PLUGIN)**
-```
-https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/plugins/plugins/oled-theme/dist/
-```
-https://github.com/user-attachments/assets/15192950-1c4b-44d6-8e42-34ae5d7d1980
-
+1. Build the plugin using `pnpm run build` in the Luna plugin root
+2. Install the generated `luna.oled-theme.mjs` file in Luna
+3. ~~Or install directly from the URL: `https://your-repository/releases/download/latest/luna.oled-theme`~~
-### Clean Lyrics (Not fullscreen)
-**(load it as a plugin)**
+## Author
-```
-https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/dist/
-```
\ No newline at end of file
+- **itzzexcel** - [GitHub](https://github.com/ItzzExcel)
+
+## Credits
+
+Original Neptune version by itzzexcel. Ported to Luna framework following the Luna plugin template structure by meowarex with help from Inrixia <3
\ No newline at end of file
diff --git a/esbuild.config.ts b/esbuild.config.ts
new file mode 100644
index 0000000..24ed40f
--- /dev/null
+++ b/esbuild.config.ts
@@ -0,0 +1 @@
+import "luna/buildPlugins";
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..9cb7447
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@itzzexcel/oled-theme",
+ "description": "A working theme, ong.",
+ "type": "module",
+ "scripts": {
+ "watch": "concurrently \"pnpm:build --watch\" pnpm:serve",
+ "build": "rimraf ./dist && tsx esbuild.config.ts",
+ "serve": "http-server ./dist -p 3000 -s --cors -c-1"
+ },
+ "devDependencies": {
+ "@types/node": "^22.15.29",
+ "@types/react": "^19.1.6",
+ "@types/react-dom": "^19.1.5",
+ "concurrently": "^9.1.2",
+ "http-server": "^14.1.1",
+ "luna": "github:Inrixia/TidaLuna#81369c7",
+ "oby": "^15.1.2",
+ "rimraf": "^6.0.1",
+ "tsx": "^4.19.4",
+ "typescript": "^5.8.3"
+ }
+}
\ No newline at end of file
diff --git a/plugins/README.md b/plugins/README.md
deleted file mode 100644
index 9623a4c..0000000
--- a/plugins/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# neptune plugin template
-This is a repository template for a neptune plugin monorepo.
-
-Each plugin in the `plugins/` directory will be automatically built by running `pnpm run build` to their respective `dist/` folder.
\ No newline at end of file
diff --git a/plugins/build.js b/plugins/build.js
deleted file mode 100644
index ab9ce41..0000000
--- a/plugins/build.js
+++ /dev/null
@@ -1,104 +0,0 @@
-const esbuild = require("esbuild");
-const fs = require("fs");
-const path = require("path");
-const crypto = require("crypto");
-
-const nativeExternals = ["@plugin", "electron", "@neptune-types", "@neptune"];
-
-const plugins = fs.readdirSync("./plugins");
-for (const plugin of plugins) {
- let pluginPath = path.join("./plugins/", plugin);
-
- const pluginManifest = JSON.parse(
- fs.readFileSync(path.join(pluginPath, "plugin.json"))
- );
-
- const outfile = path.join(pluginPath, "dist/index.js");
-
- esbuild
- .build({
- entryPoints: [
- "./" + path.join(pluginPath, pluginManifest.main ?? "index.js"),
- ],
- logLevel: "debug",
- plugins: [
- {
- name: "neptuneNativeImports",
- setup(build) {
- build.onLoad(
- { filter: /.*[\/\\].+\.native\.[a-z]+/g },
- async (args) => {
- const result = await esbuild.build({
- entryPoints: [args.path],
- bundle: true,
- minify: true,
- platform: "node",
- format: "iife",
- globalName: "neptuneExports",
- write: false,
- external: nativeExternals
- });
-
- const outputCode = result.outputFiles[0].text;
-
- // HATE! WHY WHY WHY WHY WHY (globalName breaks metafile. crying emoji)
- const { metafile } = await esbuild.build({
- entryPoints: [args.path],
- platform: "node",
- write: false,
- metafile: true,
- bundle: true, // I find it annoying that I have to enable bundling.
- format: "esm", // This avoids exports not being properly defined, thus you do not need to change log levels.
- external: nativeExternals,
- });
-
- const builtExports = Object.values(metafile.outputs)[0].exports;
-
- return {
- contents: `import {addUnloadable} from "@plugin";const contextId=NeptuneNative.createEvalScope(${JSON.stringify(
- outputCode
- )});${builtExports
- .map(
- (e) =>
- `export ${e == "default" ? "default " : `const ${e} =`
- } NeptuneNative.getNativeValue(contextId,${JSON.stringify(
- e
- )})`
- )
- .join(
- ";"
- )};addUnloadable(() => NeptuneNative.deleteEvalScope(contextId))`,
- };
- }
- );
- },
- },
- ],
- bundle: true,
- minify: true,
- format: "esm",
- external: nativeExternals,
- platform: "browser",
- outfile,
- metafile: true, // Add this line to generate a metafile
- })
- .then((result) => {
- fs.createReadStream(outfile)
- // It being md5 does not matter, this is for caching and not security
- .pipe(crypto.createHash("md5").setEncoding("hex"))
- .on("finish", function () {
- fs.writeFileSync(
- path.join(pluginPath, "dist/manifest.json"),
- JSON.stringify({
- name: pluginManifest.name,
- description: pluginManifest.description,
- author: pluginManifest.author,
- hash: this.read(),
- metafile: result.metafile, // Add this line to include the metafile in the manifest
- })
- );
-
- console.log("Built " + pluginManifest.name + "!");
- });
- });
-}
\ No newline at end of file
diff --git a/plugins/clean-view-luna/README.md b/plugins/clean-view-luna/README.md
new file mode 100644
index 0000000..1a1aebe
--- /dev/null
+++ b/plugins/clean-view-luna/README.md
@@ -0,0 +1 @@
+# WIP
\ No newline at end of file
diff --git a/plugins/clean-view-luna/package.json b/plugins/clean-view-luna/package.json
new file mode 100644
index 0000000..63fa5fc
--- /dev/null
+++ b/plugins/clean-view-luna/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@itzzexcel/clean-view",
+ "description": "Make your \"Now Playing View\" clean wherever you want, heavily based in beautiful-lyrics from @surfbryce!.",
+ "author": {
+ "name": "itzzexcel",
+ "url": "https://github.com/ItzzExcel",
+ "avatarUrl": "https://avatars.githubusercontent.com/u/ItzzExcel"
+ },
+ "main": "./src/index.ts",
+ "type": "module"
+}
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/src/index.js b/plugins/clean-view-luna/src/index.ts
similarity index 57%
rename from plugins/plugins/not-actual-fullscreen/src/index.js
rename to plugins/clean-view-luna/src/index.ts
index 5ad31e7..7babaf9 100644
--- a/plugins/plugins/not-actual-fullscreen/src/index.js
+++ b/plugins/clean-view-luna/src/index.ts
@@ -1,9 +1,10 @@
-require("./tracer");
-import { Tracer } from "./tracer";
-import * as ui from "./ui";
-import { intercept, store, utils } from "@neptune"
+import { LunaUnload, Tracer, ftch } from "@luna/core";
-const trace = Tracer("[Clean View]");
+export const { trace } = Tracer("[Clean View]");
+
+
+// clean up resources
+export const unloads = new Set();
const styles = `
[data-test="footer-player"], [class*="tabItems"] {
@@ -37,71 +38,75 @@ const styles = `
}
`;
-function ApplyCSS(style) {
+const themeUrl = "https://raw.githubusercontent.com/itzzexcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css";
+
+function ApplyCSS(style: string): HTMLStyleElement {
const styleElement = document.createElement("style");
styleElement.type = "text/css";
- if (styleElement.styleSheet) styleElement.styleSheet.cssText = style;
- else styleElement.appendChild(document.createTextNode(style));
-
+ styleElement.textContent = style;
document.head.appendChild(styleElement);
return styleElement;
}
-async function HttpGet(url) {
+async function HttpGet(url: string): Promise {
try {
- const response = await fetch(url);
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
- const content = await response.text();
+ const content = await ftch.text(url);
return content;
} catch (error) {
- trace.msg.err(`Failed to fetch URL: ${error.message}`);
+ trace.msg.err(`Failed to fetch URL: ${error instanceof Error ? error.message : String(error)}`);
return null;
}
}
var isCleanView = false;
-var appliedStyle;
-const toggleCleanButton = ui.NewPlayerButton(() => {
- if (isCleanView) {
- if (appliedStyle) {
- appliedStyle.remove();
+var appliedStyle: HTMLStyleElement | null = null;
+
+const toggleCleanButton = function(callback: () => void, icon: string, customIndex: number = 2): void {
+ setTimeout(() => {
+ const iconHolder = document.querySelector("[class*=\"_moreContainer\"");
+ if (!iconHolder) return;
+
+ const button = document.createElement("button");
+ button.style.width = "40px";
+ button.style.border = "none";
+ button.classList.add("xcl_customButton");
+
+ const buttonIcon = document.createElement("img");
+ buttonIcon.src = icon;
+ buttonIcon.style.width = "100%";
+ buttonIcon.style.height = "100%";
+ button.onclick = callback;
+
+ button.appendChild(buttonIcon);
+
+ const children = Array.from(iconHolder.children);
+ if (customIndex <= children.length) {
+ iconHolder.insertBefore(button, children[customIndex - 1]);
+ } else {
+ iconHolder.appendChild(button);
}
- } else {
- appliedStyle = ApplyCSS(styles);
- }
- isCleanView = !isCleanView;
-}, "https://lexploits.top/favicon.ico", 2);
+ }, 1000);
+};
-// STYLES FOR THE LYRICS
-const themeUrl = "https://raw.githubusercontent.com/itzzexcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css";
-
-var style;
-var styleElement;
-
-(async () => {
- style = await HttpGet(themeUrl);
- styleElement = ApplyCSS(style);
-})();
-
-
-function observeTrackTitle() {
+function observeTrackTitle(): void {
const trackTitleElement = document.querySelector('[class^="_trackTitleContainer"]');
if (trackTitleElement) {
- trackTitleElement.addEventListener('DOMSubtreeModified', () => {
+ const observer = new MutationObserver(() => {
setTimeout(() => {
- // console.log("Track changed: " + trackTitleElement.querySelector("span").innerHTML + "\n")
onTrackChanged();
}, 300);
});
+
+ observer.observe(trackTitleElement, {
+ childList: true,
+ subtree: true
+ });
+
+ unloads.add(() => observer.disconnect());
}
}
-const onTrackChanged = function (method = 0) {
- // Tu amor tan liminal, tu amor tan liminal
- // - Ghouljaboy, 2021
-
+const onTrackChanged = function (method: number = 0): void {
if (method === 1) {
setTimeout(() => {
onTrackChanged();
@@ -109,29 +114,31 @@ const onTrackChanged = function (method = 0) {
}, 2000);
}
- let albumImageElement = document.querySelector('figure[class*="_albumImage"] > div > div > div > img');
- let albumImageSrc;
+ let albumImageElement = document.querySelector('figure[class*="_albumImage"] > div > div > div > img') as HTMLImageElement;
+ let albumImageSrc: string | null = null;
if (albumImageElement) {
albumImageSrc = albumImageElement.src;
-
- // Set res to 1280x1280
- albumImageSrc = albumImageSrc.replace(/\d+x\d+/, '1280x1280');
- albumImageElement.src = albumImageSrc;
- } else if (albumImageElement = document.querySelector('figure[class*="_albumImage"] > div > div > div > video')) {
- albumImageSrc = albumImageElement.getAttribute("poster");
-
// Set res to 1280x1280
albumImageSrc = albumImageSrc.replace(/\d+x\d+/, '1280x1280');
albumImageElement.src = albumImageSrc;
} else {
- cleanUpDynamicArt();
- console.log("Couldn't get album art");
-
+ const videoElement = document.querySelector('figure[class*="_albumImage"] > div > div > div > video') as HTMLVideoElement;
+ if (videoElement) {
+ albumImageSrc = videoElement.getAttribute("poster");
+ if (albumImageSrc) {
+ // Set res to 1280x1280
+ albumImageSrc = albumImageSrc.replace(/\d+x\d+/, '1280x1280');
+ }
+ } else {
+ cleanUpDynamicArt();
+ console.log("Couldn't get album art");
+ return;
+ }
}
// Setting background to the *="nowPlayingContainer" element
- let nowPlayingContainerElement = document.querySelector('[class*="_nowPlayingContainer"]');
+ const nowPlayingContainerElement = document.querySelector('[class*="_nowPlayingContainer"]') as HTMLElement;
if (nowPlayingContainerElement && albumImageSrc) {
// Remove existing corner images if they exist
const existingImages = nowPlayingContainerElement.querySelectorAll('.corner-image');
@@ -184,31 +191,34 @@ const onTrackChanged = function (method = 0) {
}
};
-const cleanUpDynamicArt = function () {
- [...document.getElementsByClassName("corner-image")].forEach((element) => {
+const cleanUpDynamicArt = function (): void {
+ const cornerImages = document.getElementsByClassName("corner-image");
+ Array.from(cornerImages).forEach((element) => {
element.remove();
});
};
-const PLAYBACK_EVENTS = [
- "playbackControls/PREFILL_MEDIA_PRODUCT_TRANSITION",
- "playbackControls/MEDIA_PRODUCT_TRANSITION"
-];
+// STYLES FOR THE LYRICS - Added Top-level async since Luna plugins are modules <3
+const style = await HttpGet(themeUrl);
+const styleElement = style ? ApplyCSS(style) : null;
-const unsubscribeFunctions = PLAYBACK_EVENTS.map(event =>
- intercept(event, () => {
- onTrackChanged(1);
- })
-);
+const toggleCleanButtonInstance = toggleCleanButton(() => {
+ if (isCleanView) {
+ if (appliedStyle) {
+ appliedStyle.remove();
+ appliedStyle = null;
+ }
+ } else {
+ appliedStyle = ApplyCSS(styles);
+ }
+ isCleanView = !isCleanView;
+}, "https://lexploits.top/favicon.ico", 2);
observeTrackTitle();
-observeTrackTitle();
-observeTrackTitle();
-observeTrackTitle();
-
onTrackChanged(1);
-function CleanUpCSS() {
+// Add cleanup to unloads
+unloads.add(() => {
if (styleElement && styleElement.parentNode) {
styleElement.parentNode.removeChild(styleElement);
}
@@ -216,16 +226,18 @@ function CleanUpCSS() {
if (appliedStyle && appliedStyle.parentNode) {
appliedStyle.parentNode.removeChild(appliedStyle);
}
-}
-export function onUnload() {
- CleanUpCSS();
- ui.CleanupButtons();
- unsubscribeFunctions.forEach(unsubscribe => unsubscribe());
cleanUpDynamicArt();
- const trackTitleElement = document.querySelector('div[class^="_trackTitleContainer"]');
- if (trackTitleElement) {
- trackTitleElement.removeEventListener('DOMSubtreeModified', onTrackChanged);
+ // Clean up custom buttons
+ const customButtons = document.getElementsByClassName("xcl_customButton");
+ Array.from(customButtons).forEach(element => {
+ element.remove();
+ });
+
+ // Clean up spin animation
+ const spinAnimationStyle = document.querySelector('#spinAnimation');
+ if (spinAnimationStyle && spinAnimationStyle.parentNode) {
+ spinAnimationStyle.parentNode.removeChild(spinAnimationStyle);
}
-}
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/plugins/copy-lyrics-luna/README.md b/plugins/copy-lyrics-luna/README.md
new file mode 100644
index 0000000..1a1aebe
--- /dev/null
+++ b/plugins/copy-lyrics-luna/README.md
@@ -0,0 +1 @@
+# WIP
\ No newline at end of file
diff --git a/plugins/copy-lyrics-luna/package.json b/plugins/copy-lyrics-luna/package.json
new file mode 100644
index 0000000..397b085
--- /dev/null
+++ b/plugins/copy-lyrics-luna/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@itzzexcel/copy-lyrics",
+ "description": "A working neptune plugin that allows the user to copy the lyrics of a song selecting it.",
+ "author": {
+ "name": "itzzexcel",
+ "url": "https://github.com/ItzzExcel",
+ "avatarUrl": "https://avatars.githubusercontent.com/u/ItzzExcel"
+ },
+ "main": "./src/index.ts",
+ "type": "module"
+}
\ No newline at end of file
diff --git a/plugins/plugins/copy-lyrics/src/index.js b/plugins/copy-lyrics-luna/src/index.ts
similarity index 75%
rename from plugins/plugins/copy-lyrics/src/index.js
rename to plugins/copy-lyrics-luna/src/index.ts
index 3213da7..5496f1a 100644
--- a/plugins/plugins/copy-lyrics/src/index.js
+++ b/plugins/copy-lyrics-luna/src/index.ts
@@ -1,7 +1,10 @@
-require("./tracer");
-import { Tracer } from "./tracer";
+import { LunaUnload, Tracer } from "@luna/core";
-const trace = Tracer("[Copy Lyrics]");
+export const { trace } = Tracer("[Copy Lyrics]");
+
+
+// clean up resources
+export const unloads = new Set();
const unlockSelection = `
[class^="_lyricsText"]>div>span {
@@ -15,17 +18,15 @@ const unlockSelection = `
}
`;
-function ApplyCSS(style) {
+function ApplyCSS(style: string): HTMLStyleElement {
const styleElement = document.createElement("style");
styleElement.type = "text/css";
- if (styleElement.styleSheet) styleElement.styleSheet.cssText = style;
- else styleElement.appendChild(document.createTextNode(style));
-
+ styleElement.textContent = style;
document.head.appendChild(styleElement);
return styleElement;
}
-function SetClipboard(text) {
+function SetClipboard(text: string): void {
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed"; // Avoid scrolling to bottom
@@ -36,7 +37,7 @@ function SetClipboard(text) {
const success = document.execCommand("copy");
if (!success) throw new Error("Failed to copy text.");
} catch (err) {
- trace.msg.err(err);
+ trace.msg.err(err instanceof Error ? err.message : String(err));
} finally {
document.body.removeChild(textarea);
}
@@ -46,38 +47,38 @@ const styleElement = ApplyCSS(unlockSelection);
let isSelecting = false;
-const onMouseDown = function () {
+const onMouseDown = function (): void {
isSelecting = true;
};
-const onMouseUp = function (event) {
+const onMouseUp = function (event: MouseEvent): void {
if (isSelecting) {
const selection = window.getSelection();
- if (selection.toString().length > 0) {
- const selectedSpans = [];
+ if (selection && selection.toString().length > 0) {
+ const selectedSpans: HTMLSpanElement[] = [];
const range = selection.getRangeAt(0);
let container = range.commonAncestorContainer;
- // If the container is NOT and element and a document, try to adjust it.
+
+ // If the container is NOT an element and a document, adjust it.
if (
container.nodeType !== Node.ELEMENT_NODE &&
container.nodeType !== Node.DOCUMENT_NODE
) {
// Get the parent element if it's a text node
const parentElement = container.parentElement;
- if (parentElement && parentElement.hasAttribute("data-current") || container.ELEMENT_NODE.hasAttribute("data-current")) {
+ if (parentElement && parentElement.hasAttribute("data-current")) {
let text_ = selection.toString().trim();
SetClipboard(text_);
trace.msg.log("Copied to clipboard!");
-
return;
}
}
// Get all the spans inside the container.
- const spans = container.getElementsByTagName("span");
+ const spans = (container as Element).getElementsByTagName("span");
for (let span of spans) {
if (selection.containsNode(span, true)) {
- selectedSpans.push(span);
+ selectedSpans.push(span as HTMLSpanElement);
}
}
@@ -94,29 +95,22 @@ const onMouseUp = function (event) {
}
});
- if (hasCorrectAttribute) {
- console.log(hasCorrectAttribute);
- }
-
text = text.trim();
- if (hasCorrectAttribute === true) {
+ if (hasCorrectAttribute) {
SetClipboard(text);
trace.msg.log("Copied to clipboard!");
- if (window.getSelection) {
- selection.removeAllRanges();
- }
+ selection.removeAllRanges();
}
-
}
isSelecting = false;
}
};
-const onClickHooked = function (event) {
+const onClickHooked = function (event: MouseEvent): boolean | void {
if (!isSelecting) return;
- const target = event.target;
+ const target = event.target as HTMLElement;
if (target.tagName.toLowerCase() === "span" && target.hasAttribute("data-current")) {
// Prevent default behavior and stop event propagation
event.preventDefault();
@@ -131,8 +125,9 @@ document.addEventListener("click", onClickHooked, true);
document.addEventListener("mousedown", onMouseDown);
document.addEventListener("mouseup", onMouseUp);
-export function onUnload() {
- if (styleElement && styleElement.parentNode) {
+// Add cleanup to unloads
+unloads.add(() => {
+ if (styleElement.parentNode) {
styleElement.parentNode.removeChild(styleElement);
}
@@ -140,4 +135,4 @@ export function onUnload() {
document.removeEventListener("click", onClickHooked, true);
document.removeEventListener("mousedown", onMouseDown);
document.removeEventListener("mouseup", onMouseUp);
-}
+});
\ No newline at end of file
diff --git a/plugins/oled-theme-luna/README.md b/plugins/oled-theme-luna/README.md
new file mode 100644
index 0000000..fd3dd4d
--- /dev/null
+++ b/plugins/oled-theme-luna/README.md
@@ -0,0 +1,26 @@
+# OLED Theme Luna Plugin
+
+This is a port of the OLED Theme plugin from Neptune to Luna framework.
+
+## Description
+
+A working theme plugin that applies a dark OLED-friendly theme to Tidal Luna.
+
+## Features
+
+- Applies a dark, OLED-optimized theme
+- Fetches the latest theme CSS from the GitHub repository
+
+## Installation
+
+1. Build the plugin using `pnpm run build` in the Luna plugin root
+2. Install the generated `luna.oled-theme.mjs` file in Luna
+3. ~~Or install directly from the URL: `https://your-repository/releases/download/latest/luna.oled-theme`~~
+
+## Author
+
+- **itzzexcel** - [GitHub](https://github.com/ItzzExcel)
+
+## Credits
+
+Original Neptune version by itzzexcel. Ported to Luna framework following the Luna plugin template structure by meowarex with help from Inrixia <3
\ No newline at end of file
diff --git a/plugins/oled-theme-luna/package.json b/plugins/oled-theme-luna/package.json
new file mode 100644
index 0000000..ce183b8
--- /dev/null
+++ b/plugins/oled-theme-luna/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@itzzexcel/oled-theme",
+ "description": "A working theme, ong.",
+ "author": {
+ "name": "itzzexcel",
+ "url": "https://github.com/ItzzExcel",
+ "avatarUrl": "https://avatars.githubusercontent.com/u/ItzzExcel"
+ },
+ "main": "./src/index.ts",
+ "type": "module"
+}
\ No newline at end of file
diff --git a/themes/black-neptune-theme.css b/plugins/oled-theme-luna/src/index.css
similarity index 100%
rename from themes/black-neptune-theme.css
rename to plugins/oled-theme-luna/src/index.css
diff --git a/plugins/oled-theme-luna/src/index.ts b/plugins/oled-theme-luna/src/index.ts
new file mode 100644
index 0000000..9c3573b
--- /dev/null
+++ b/plugins/oled-theme-luna/src/index.ts
@@ -0,0 +1,30 @@
+import { LunaUnload, Tracer, ftch } from "@luna/core";
+
+export const { trace } = Tracer("[OLED Theme]");
+
+const themeUrl = "https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/themes/black-neptune-theme.css";
+
+// called when plugin is unloaded.
+// clean up resources
+export const unloads = new Set();
+
+// Added Top-level async since Luna plugins are modules <3
+const style = await ftch.text(themeUrl).catch((error: Error) => {
+ trace.msg.err(`Failed to fetch theme CSS: ${error.message}`);
+ return null;
+});
+
+// Apply the OLED theme if CSS was fetched successfully
+if (style) {
+ const styleElement = document.createElement("style");
+ styleElement.type = "text/css";
+ styleElement.textContent = style;
+ document.head.appendChild(styleElement);
+
+ // Add cleanup to unloads
+ unloads.add(() => {
+ if (styleElement.parentNode) {
+ styleElement.parentNode.removeChild(styleElement);
+ }
+ });
+}
\ No newline at end of file
diff --git a/plugins/oled-theme-luna/src/types.d.ts b/plugins/oled-theme-luna/src/types.d.ts
new file mode 100644
index 0000000..72a2c2c
--- /dev/null
+++ b/plugins/oled-theme-luna/src/types.d.ts
@@ -0,0 +1,4 @@
+declare module "*.css" {
+ const content: string;
+ export default content;
+}
\ No newline at end of file
diff --git a/plugins/package-lock.json b/plugins/package-lock.json
deleted file mode 100644
index 455b5fa..0000000
--- a/plugins/package-lock.json
+++ /dev/null
@@ -1,550 +0,0 @@
-{
- "name": "neptune-plugin-template",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "neptune-plugin-template",
- "dependencies": {
- "canvas-confetti": "^1.9.3",
- "neptune-types": "^1.0.1",
- "wanakana": "^5.3.1"
- },
- "devDependencies": {
- "esbuild": "^0.18.13"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz",
- "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==",
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/canvas-confetti": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz",
- "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==",
- "license": "ISC",
- "funding": {
- "type": "donate",
- "url": "https://www.paypal.me/kirilvatev"
- }
- },
- "node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
- }
- },
- "node_modules/htm": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz",
- "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==",
- "license": "Apache-2.0"
- },
- "node_modules/idb-keyval": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz",
- "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==",
- "license": "Apache-2.0"
- },
- "node_modules/immutable": {
- "version": "5.0.0-beta.4",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.0-beta.4.tgz",
- "integrity": "sha512-sl9RE3lqd2LoQSESc8VV0k8qE9y57iT7dinq3Q+8mR2dqReHDZlgUrudzmFfZhDXBLXlNJMVWv3SG1YpQIokig==",
- "license": "MIT"
- },
- "node_modules/neptune-types": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/neptune-types/-/neptune-types-1.0.1.tgz",
- "integrity": "sha512-XDkESq/jNTH9La//peJQirzJTwJySxkc4pCjHz1RtgcmoFbYIZ72JR0mkFYNsCZ0oyI7gLgaApd405VzU1gqOw==",
- "license": "MS-PL",
- "dependencies": {
- "idb-keyval": "^6.2.1",
- "immutable": "5.0.0-beta.4",
- "redux": "^4.2.1",
- "spitroast": "^1.4.3",
- "type-fest": "^4.3.1",
- "voby": "^0.54.0",
- "zod": "^3.2.2"
- }
- },
- "node_modules/oby": {
- "version": "14.3.5",
- "resolved": "https://registry.npmjs.org/oby/-/oby-14.3.5.tgz",
- "integrity": "sha512-0RgL6n1qmxdkUgvXFnmG/J+Lv8HWjwnWmULtu/omMxRUV9KhD/8x3sL7DmanUvEOi5wX4xTbef1sKe5NzqGm7g=="
- },
- "node_modules/redux": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
- "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.9.2"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "license": "MIT"
- },
- "node_modules/spitroast": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/spitroast/-/spitroast-1.4.4.tgz",
- "integrity": "sha512-S69rzIFjbGoEW5YCLpm1kEdqMEYqC09lmE1ZMY4gyUXfke0wi9qZjKYa0DDSv5eIy/D+/UGJT8yxgJddU3oqlA==",
- "license": "CC0-1.0"
- },
- "node_modules/type-fest": {
- "version": "4.34.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.34.1.tgz",
- "integrity": "sha512-6kSc32kT0rbwxD6QL1CYe8IqdzN/J/ILMrNK+HMQCKH3insCDRY/3ITb0vcBss0a3t72fzh2YSzj8ko1HgwT3g==",
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/voby": {
- "version": "0.54.0",
- "resolved": "https://registry.npmjs.org/voby/-/voby-0.54.0.tgz",
- "integrity": "sha512-hH8LXcP0QR4J6nnzfSWGD13onq7hqdc/ya1r1Bb+TxibtECYKZRO1m4HdSU4RcE7MdAaQwR5pwgd+hqXCqk2OA==",
- "dependencies": {
- "htm": "^3.1.1",
- "oby": "^14.3.0"
- }
- },
- "node_modules/wanakana": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/wanakana/-/wanakana-5.3.1.tgz",
- "integrity": "sha512-OSDqupzTlzl2LGyqTdhcXcl6ezMiFhcUwLBP8YKaBIbMYW1wAwDvupw2T9G9oVaKT9RmaSpyTXjxddFPUcFFIw==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/zod": {
- "version": "3.24.2",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
- "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/plugins/package.json b/plugins/package.json
deleted file mode 100644
index 8b67891..0000000
--- a/plugins/package.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "name": "neptune-plugin-template",
- "description": "A neptune plugin monorepo template",
- "main": "index.js",
- "scripts": {
- "build": "node ./build.js"
- },
- "devDependencies": {
- "esbuild": "^0.18.13"
- },
- "dependencies": {
- "canvas-confetti": "^1.9.3",
- "neptune-types": "^1.0.1",
- "wanakana": "^5.3.1"
- }
-}
diff --git a/plugins/plugins/copy-lyrics/dist/index.js b/plugins/plugins/copy-lyrics/dist/index.js
deleted file mode 100644
index e88e185..0000000
--- a/plugins/plugins/copy-lyrics/dist/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var E=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var O=(t,e)=>()=>(t&&(e=t(t=0)),e);var R=(t,e)=>{for(var r in e)E(t,r,{get:e[r],enumerable:!0})},_=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of L(e))!A.call(t,o)&&o!==r&&E(t,o,{get:()=>e[o],enumerable:!(i=v(e,o))||i.enumerable});return t};var k=t=>_(E({},"__esModule",{value:!0}),t);var y={};R(y,{Tracer:()=>m,libTrace:()=>D});import{actions as h}from"@neptune";var m,D,C=O(()=>{"use strict";m=t=>{let e=s=>{let n=(...c)=>{s(t,...c)};return n.withContext=c=>(...u)=>{s(t,c,...u)},n},r=e(console.log),i=e(console.warn),o=e(console.error),f=e(console.debug),a=(s,n,c)=>{let u=d=>{s(d),n({message:`${t} - ${d}`,category:"OTHER",severity:c})};return u.withContext=d=>{let S=s.withContext(d);return l=>{S(l),l instanceof Error&&(l=l.message),n({message:`${t}.${d} - ${l}`,category:"OTHER",severity:c})}},u};return{log:r,warn:i,err:o,debug:f,msg:{log:a(r,h.message.messageInfo,"INFO"),warn:a(i,h.message.messageWarn,"WARN"),err:a(o,h.message.messageError,"ERROR")}}},D=m("[lib]")});C();C();var x=m("[Copy Lyrics]"),M=`
-[class^="_lyricsText"]>div>span {
- user-select: text;
- cursor: text;
-}
-
-::selection {
- background: rgb(0, 0, 0);
- color: rgb(255, 255, 255);
-}
-`;function $(t){let e=document.createElement("style");return e.type="text/css",e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t)),document.head.appendChild(e),e}function b(t){let e=document.createElement("textarea");e.value=t,e.style.position="fixed",document.body.appendChild(e),e.select();try{if(!document.execCommand("copy"))throw new Error("Failed to copy text.")}catch(r){x.msg.err(r)}finally{document.body.removeChild(e)}}var g=$(M),p=!1,w=function(){p=!0},N=function(t){if(p){let e=window.getSelection();if(e.toString().length>0){let r=[],o=e.getRangeAt(0).commonAncestorContainer;if(o.nodeType!==Node.ELEMENT_NODE&&o.nodeType!==Node.DOCUMENT_NODE){let n=o.parentElement;if(n&&n.hasAttribute("data-current")||o.ELEMENT_NODE.hasAttribute("data-current")){let c=e.toString().trim();b(c),x.msg.log("Copied to clipboard!");return}}let f=o.getElementsByTagName("span");for(let n of f)e.containsNode(n,!0)&&r.push(n);let a=!1,s="";r.forEach(n=>{n.hasAttribute("data-current")&&(a=!0,s+=n.textContent+`
-`,[...n.classList].some(c=>c.startsWith("endOfStanza--"))&&(s+=`
-`))}),a&&console.log(a),s=s.trim(),a===!0&&(b(s),x.msg.log("Copied to clipboard!"),window.getSelection&&e.removeAllRanges())}p=!1}},T=function(t){if(!p)return;let e=t.target;if(e.tagName.toLowerCase()==="span"&&e.hasAttribute("data-current"))return t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),!1};document.addEventListener("click",T,!0);document.addEventListener("mousedown",w);document.addEventListener("mouseup",N);function U(){g&&g.parentNode&&g.parentNode.removeChild(g),document.removeEventListener("click",T,!0),document.removeEventListener("mousedown",w),document.removeEventListener("mouseup",N)}export{U as onUnload};
diff --git a/plugins/plugins/copy-lyrics/dist/manifest.json b/plugins/plugins/copy-lyrics/dist/manifest.json
deleted file mode 100644
index b3fc9d5..0000000
--- a/plugins/plugins/copy-lyrics/dist/manifest.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"Copy Lyrics","description":"A working neptune plugin that allows the user to copy the lyrics of a song selecting it.","author":"itzzexcel@github","hash":"e9cb09fb13455726d61951a9de2571f8","metafile":{"inputs":{"plugins/copy-lyrics/src/tracer.js":{"bytes":1596,"imports":[{"path":"@neptune","kind":"import-statement","external":true}],"format":"esm"},"plugins/copy-lyrics/src/index.js":{"bytes":4702,"imports":[{"path":"plugins/copy-lyrics/src/tracer.js","kind":"import-statement","original":"./tracer"},{"path":"plugins/copy-lyrics/src/tracer.js","kind":"require-call","original":"./tracer"}],"format":"esm"}},"outputs":{"plugins/copy-lyrics/dist/index.js":{"imports":[{"path":"@neptune","kind":"import-statement","external":true}],"exports":["onUnload"],"entryPoint":"plugins/copy-lyrics/src/index.js","inputs":{"plugins/copy-lyrics/src/tracer.js":{"bytesInOutput":693},"plugins/copy-lyrics/src/index.js":{"bytesInOutput":1915}},"bytes":3078}}}}
\ No newline at end of file
diff --git a/plugins/plugins/copy-lyrics/package.json b/plugins/plugins/copy-lyrics/package.json
deleted file mode 100644
index d020e40..0000000
--- a/plugins/plugins/copy-lyrics/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "canvas-confetti": "^1.6.0",
- "neptune-types": "1.0.1"
- }
-}
\ No newline at end of file
diff --git a/plugins/plugins/copy-lyrics/plugin.json b/plugins/plugins/copy-lyrics/plugin.json
deleted file mode 100644
index f891840..0000000
--- a/plugins/plugins/copy-lyrics/plugin.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "Copy Lyrics",
- "description": "A working neptune plugin that allows the user to copy the lyrics of a song selecting it.",
- "author": "itzzexcel@github",
- "main": "./src/index.js"
-}
\ No newline at end of file
diff --git a/plugins/plugins/copy-lyrics/pnpm-lock.yaml b/plugins/plugins/copy-lyrics/pnpm-lock.yaml
deleted file mode 100644
index 1d2e826..0000000
--- a/plugins/plugins/copy-lyrics/pnpm-lock.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-lockfileVersion: '6.1'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-dependencies:
- canvas-confetti:
- specifier: ^1.6.0
- version: 1.6.0
-
-packages:
-
- /canvas-confetti@1.6.0:
- resolution: {integrity: sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA==}
- dev: false
diff --git a/plugins/plugins/copy-lyrics/src/tracer.js b/plugins/plugins/copy-lyrics/src/tracer.js
deleted file mode 100644
index f18bcd3..0000000
--- a/plugins/plugins/copy-lyrics/src/tracer.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Based on https://github.com/Inrixia/neptune-plugins/blob/3d28c9ea3252782da830698032dbb49dbe5b9fd6/plugins/_lib/trace.ts
-// Credits to inrixia
-
-import { actions } from "@neptune";
-
-export const Tracer = (source) => {
- const createLogger = (logger) => {
- const _logger = (...data) => {
- logger(source, ...data);
- return undefined;
- };
- _logger.withContext = (context) => (...data) => {
- logger(source, context, ...data);
- return undefined;
- };
- return _logger;
- };
-
- const log = createLogger(console.log);
- const warn = createLogger(console.warn);
- const err = createLogger(console.error);
- const debug = createLogger(console.debug);
-
- const createMessager = (logger, messager, severity) => {
- const _messager = (message) => {
- logger(message);
- messager({ message: `${source} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- _messager.withContext = (context) => {
- const loggerWithContext = logger.withContext(context);
- return (message) => {
- loggerWithContext(message);
- if (message instanceof Error) message = message.message;
- messager({ message: `${source}.${context} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- };
- return _messager;
- };
-
- return {
- log,
- warn,
- err,
- debug,
- msg: {
- log: createMessager(log, actions.message.messageInfo, "INFO"),
- warn: createMessager(warn, actions.message.messageWarn, "WARN"),
- err: createMessager(err, actions.message.messageError, "ERROR"),
- },
- };
-};
-
-export const libTrace = Tracer("[lib]");
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/dist/index.js b/plugins/plugins/not-actual-fullscreen/dist/index.js
deleted file mode 100644
index 8aaf53e..0000000
--- a/plugins/plugins/not-actual-fullscreen/dist/index.js
+++ /dev/null
@@ -1,36 +0,0 @@
-var C=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var O=(t,e)=>()=>(t&&(e=t(t=0)),e);var P=(t,e)=>{for(var n in e)C(t,n,{get:e[n],enumerable:!0})},q=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of R(e))!B.call(t,s)&&s!==n&&C(t,s,{get:()=>e[s],enumerable:!(a=k(e,s))||a.enumerable});return t};var L=t=>q(C({},"__esModule",{value:!0}),t);var x={};P(x,{Tracer:()=>g,libTrace:()=>D});import{actions as b}from"@neptune";var g,D,E=O(()=>{"use strict";g=t=>{let e=i=>{let m=(...c)=>{i(t,...c)};return m.withContext=c=>(...f)=>{i(t,c,...f)},m},n=e(console.log),a=e(console.warn),s=e(console.error),r=e(console.debug),o=(i,m,c)=>{let f=u=>{i(u),m({message:`${t} - ${u}`,category:"OTHER",severity:c})};return f.withContext=u=>{let A=i.withContext(u);return d=>{A(d),d instanceof Error&&(d=d.message),m({message:`${t}.${u} - ${d}`,category:"OTHER",severity:c})}},f};return{log:n,warn:a,err:s,debug:r,msg:{log:o(n,b.message.messageInfo,"INFO"),warn:o(a,b.message.messageWarn,"WARN"),err:o(s,b.message.messageError,"ERROR")}}},D=g("[lib]")});E();var T=[];function w(t,e,n=1){setTimeout(()=>{let a=document.querySelector('[class*="_moreContainer"'),s=document.createElement("button");s.style.width="40px",s.style.border="none",s.classList.add("xcl_customButton");let r=document.createElement("img");r.src=e,r.style.width="100%",r.style.height="100%",s.onclick=t,s.appendChild(r);let o=Array.from(a.children);return n<=o.length?a.insertBefore(s,o[n-1]):a.appendChild(s),T.push(s),s},1e3)}function S(){Array.from(T).forEach(t=>{t.remove()}),Array.from(document.getElementsByClassName("xcl_customButton")).forEach(t=>{t.remove()})}import{intercept as U}from"@neptune";E();var $=g("[Clean View]"),F=`
-[data-test="footer-player"], [class*="tabItems"] {
- opacity: 0 !important;
- transition: opacity 0.3s ease-in-out;
-}
-
-[class*="_imageContainer"] {
- margin-top: 140px;
-}
-
-[data-test="footer-player"]:hover, [class*="_tabItems"]:hover {
- opacity: 1 !important;
-}
-
-[data-test="header-container"] {
- opacity: 0;
- margin: -40px;
-}
-
-[class*="_nowPlayingContainer"] {
- padding-left: 6%;
-}
-
-[class^="_bar"] {
- background-color: transparent;
-}
-
-[class^="_bar"]>* {
- opacity: 0;
-}
-`;function _(t){let e=document.createElement("style");return e.type="text/css",e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t)),document.head.appendChild(e),e}async function H(t){try{let e=await fetch(t);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return await e.text()}catch(e){return $.msg.err(`Failed to fetch URL: ${e.message}`),null}}var v=!1,l,Z=w(()=>{v?l&&l.remove():l=_(F),v=!v},"https://lexploits.top/favicon.ico",2),z="https://raw.githubusercontent.com/itzzexcel/neptune-projects/refs/heads/main/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css",I,p;(async()=>(I=await H(z),p=_(I)))();function h(){let t=document.querySelector('[class^="_trackTitleContainer"]');t&&t.addEventListener("DOMSubtreeModified",()=>{setTimeout(()=>{y()},300)})}var y=function(t=0){t===1&&setTimeout(()=>{y()},2e3);let e=document.querySelector('figure[class*="_albumImage"] > div > div > div > img'),n;e?(n=e.src,n=n.replace(/\d+x\d+/,"1280x1280"),e.src=n):(e=document.querySelector('figure[class*="_albumImage"] > div > div > div > video'))?(n=e.getAttribute("poster"),n=n.replace(/\d+x\d+/,"1280x1280"),e.src=n):(N(),console.log("Couldn't get album art"));let a=document.querySelector('[class*="_nowPlayingContainer"]');if(a&&n){a.querySelectorAll(".corner-image").forEach(i=>i.remove());let r=document.createElement("img");r.src=n,r.className="corner-image",r.style.position="absolute",r.style.left="50%",r.style.top="50%",r.style.transform="translate(-50%, -50%)",r.style.width="75vw",r.style.height="150vh",r.style.objectFit="cover",r.style.zIndex="-1",r.style.filter="blur(100px) brightness(0.4) contrast(1.2) saturate(1)",r.style.animation="spin 35s linear infinite",r.style.animationDelay="5s",a.appendChild(r);let o=document.createElement("img");if(o.src=n,o.className="corner-image",o.style.position="absolute",o.style.left="50%",o.style.top="50%",o.style.transform="translate(-50%, -50%)",o.style.width="75vw",o.style.height="150vh",o.style.objectFit="cover",o.style.zIndex="-1",o.style.filter="blur(100px) brightness(0.4) contrast(1.2) saturate(1)",o.style.animation="spin 35s linear infinite",a.appendChild(o),!document.querySelector("#spinAnimation")){let i=document.createElement("style");i.id="spinAnimation",i.textContent=`
- @keyframes spin {
- from { transform: translate(-50%, -50%) rotate(0deg); }
- to { transform: translate(-50%, -50%) rotate(360deg); }
- }
- `,document.head.appendChild(i)}}},N=function(){[...document.getElementsByClassName("corner-image")].forEach(t=>{t.remove()})},j=["playbackControls/PREFILL_MEDIA_PRODUCT_TRANSITION","playbackControls/MEDIA_PRODUCT_TRANSITION"],V=j.map(t=>U(t,()=>{y(1)}));h();h();h();h();y(1);function W(){p&&p.parentNode&&p.parentNode.removeChild(p),l&&l.parentNode&&l.parentNode.removeChild(l)}function ee(){W(),S(),V.forEach(e=>e()),N();let t=document.querySelector('div[class^="_trackTitleContainer"]');t&&t.removeEventListener("DOMSubtreeModified",y)}export{ee as onUnload};
diff --git a/plugins/plugins/not-actual-fullscreen/dist/manifest.json b/plugins/plugins/not-actual-fullscreen/dist/manifest.json
deleted file mode 100644
index 4d49983..0000000
--- a/plugins/plugins/not-actual-fullscreen/dist/manifest.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"Clean View","description":"Make your \"Now Playing View\" clean wherever you want, heavily based in beautiful-lyrics from @surfbryce!.","author":"itzzexcel@github","hash":"c93ec09d958c8db4f4e7019a63f35476","metafile":{"inputs":{"plugins/not-actual-fullscreen/src/tracer.js":{"bytes":1596,"imports":[{"path":"@neptune","kind":"import-statement","external":true}],"format":"esm"},"plugins/not-actual-fullscreen/src/ui.js":{"bytes":1267,"imports":[],"format":"esm"},"plugins/not-actual-fullscreen/src/index.js":{"bytes":7427,"imports":[{"path":"plugins/not-actual-fullscreen/src/tracer.js","kind":"import-statement","original":"./tracer"},{"path":"plugins/not-actual-fullscreen/src/ui.js","kind":"import-statement","original":"./ui"},{"path":"@neptune","kind":"import-statement","external":true},{"path":"plugins/not-actual-fullscreen/src/tracer.js","kind":"require-call","original":"./tracer"}],"format":"esm"}},"outputs":{"plugins/not-actual-fullscreen/dist/index.js":{"imports":[{"path":"@neptune","kind":"import-statement","external":true},{"path":"@neptune","kind":"import-statement","external":true}],"exports":["onUnload"],"entryPoint":"plugins/not-actual-fullscreen/src/index.js","inputs":{"plugins/not-actual-fullscreen/src/tracer.js":{"bytesInOutput":693},"plugins/not-actual-fullscreen/src/index.js":{"bytesInOutput":3610},"plugins/not-actual-fullscreen/src/ui.js":{"bytesInOutput":581}},"bytes":5355}}}}
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/package.json b/plugins/plugins/not-actual-fullscreen/package.json
deleted file mode 100644
index d020e40..0000000
--- a/plugins/plugins/not-actual-fullscreen/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "canvas-confetti": "^1.6.0",
- "neptune-types": "1.0.1"
- }
-}
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/plugin.json b/plugins/plugins/not-actual-fullscreen/plugin.json
deleted file mode 100644
index 04ea0a1..0000000
--- a/plugins/plugins/not-actual-fullscreen/plugin.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "Clean View",
- "description": "Make your \"Now Playing View\" clean wherever you want, heavily based in beautiful-lyrics from @surfbryce!.",
- "author": "itzzexcel@github",
- "main": "./src/index.js"
-}
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/pnpm-lock.yaml b/plugins/plugins/not-actual-fullscreen/pnpm-lock.yaml
deleted file mode 100644
index 1d2e826..0000000
--- a/plugins/plugins/not-actual-fullscreen/pnpm-lock.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-lockfileVersion: '6.1'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-dependencies:
- canvas-confetti:
- specifier: ^1.6.0
- version: 1.6.0
-
-packages:
-
- /canvas-confetti@1.6.0:
- resolution: {integrity: sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA==}
- dev: false
diff --git a/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css b/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css
deleted file mode 100644
index 1fa163a..0000000
--- a/plugins/plugins/not-actual-fullscreen/src/separated-lyrics.css
+++ /dev/null
@@ -1,97 +0,0 @@
-/* TODO: ADD INTERLUDE SUPPORT FOR THE THREE DOTS */
-/* Credits to https://github.com/surfbryce for the fonts */
-@font-face {
- font-family: "AbyssFont";
- font-weight: 400;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsRegular.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 500;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsMedium.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 600;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsSemibold.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 700;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsBold.woff2") format("woff2");
-}
-
-[class*="_lyricsText"]>span[class*="_active"] {
- text-shadow: 0 0 2px #fff, 0 0 20px #fff;
- padding-left: 20px;
- transition-duration: 0.7s;
- font-size: 60px;
-}
-
-[class*="_lyricsText"]>span {
- text-shadow: 0 0 0px transparent, 0 0 0px transparent;
- transition-duration: 0.25s;
- color: rgba(128, 128, 128, 0.4);
- font-size: 45px;
-}
-
-[class*="_lyricsText"]>span:hover {
- text-shadow: 0 0 2px lightgray, 0 0 20px lightgray;
- color: lightgray;
- padding-left: 20px;
- transition-duration: 0.7s;
-}
-
-[data-test="now-playing-track-title"] {
- text-shadow: 0 0 1px #fff, 0 0 30px #fff;
-}
-
-[class^="_bottomGradient"] {
- visibility: hidden;
-}
-
-[aria-label="Show credits"] {
- top: calc(var(--headerHeight) + 80px);
-}
-
-[data-current] {
- transition: text-shadow 0.7s ease-in-out, text-shadow 0.7s ease-in-out padding 0.7s ease-in-out;
-}
-
-[data-current="true"] {
- text-shadow: 0 0 2px #fff, 0 0 20px #fff;
- padding-left: 20px;
- transition-duration: 0.7s;
-}
-
-[data-current="false"] {
- text-shadow: 0 0 0px transparent, 0 0 0px transparent;
- transition-duration: 0.25s;
- color: rgba(128, 128, 128, 0.4);
-}
-
-[data-current="false"]:hover {
- text-shadow: 0 0 2px lightgray, 0 0 20px lightgray;
- color: lightgray;
- padding-left: 20px;
- transition-duration: 0.7s;
-}
-
-[class^="_lyricsContainer"]>div>div>span {
- margin-bottom: 2rem;
- opacity: 1;
- font-family: "AbyssFont", system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
- font-weight: 700;
- font-size: 43px !important;
-}
-
-[class^="_lyricsProvider"] {
- visibility: hidden;
-}
-
-[class^="_syncButton"] {
- margin-bottom: 10px;
-}
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/src/tracer.js b/plugins/plugins/not-actual-fullscreen/src/tracer.js
deleted file mode 100644
index f18bcd3..0000000
--- a/plugins/plugins/not-actual-fullscreen/src/tracer.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Based on https://github.com/Inrixia/neptune-plugins/blob/3d28c9ea3252782da830698032dbb49dbe5b9fd6/plugins/_lib/trace.ts
-// Credits to inrixia
-
-import { actions } from "@neptune";
-
-export const Tracer = (source) => {
- const createLogger = (logger) => {
- const _logger = (...data) => {
- logger(source, ...data);
- return undefined;
- };
- _logger.withContext = (context) => (...data) => {
- logger(source, context, ...data);
- return undefined;
- };
- return _logger;
- };
-
- const log = createLogger(console.log);
- const warn = createLogger(console.warn);
- const err = createLogger(console.error);
- const debug = createLogger(console.debug);
-
- const createMessager = (logger, messager, severity) => {
- const _messager = (message) => {
- logger(message);
- messager({ message: `${source} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- _messager.withContext = (context) => {
- const loggerWithContext = logger.withContext(context);
- return (message) => {
- loggerWithContext(message);
- if (message instanceof Error) message = message.message;
- messager({ message: `${source}.${context} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- };
- return _messager;
- };
-
- return {
- log,
- warn,
- err,
- debug,
- msg: {
- log: createMessager(log, actions.message.messageInfo, "INFO"),
- warn: createMessager(warn, actions.message.messageWarn, "WARN"),
- err: createMessager(err, actions.message.messageError, "ERROR"),
- },
- };
-};
-
-export const libTrace = Tracer("[lib]");
\ No newline at end of file
diff --git a/plugins/plugins/not-actual-fullscreen/src/ui.js b/plugins/plugins/not-actual-fullscreen/src/ui.js
deleted file mode 100644
index d7a7ab7..0000000
--- a/plugins/plugins/not-actual-fullscreen/src/ui.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var buttonElementList = [];
-
-export function NewPlayerButton(callback, icon, customIndex = 1) {
- setTimeout(() => {
- let iconHolder = document.querySelector("[class*=\"_moreContainer\"");
-
- let button = document.createElement("button");
- button.style.width = "40px";
- button.style.border = "none";
- button.classList.add("xcl_customButton");
-
- let buttonIcon = document.createElement("img");
- buttonIcon.src = icon;
- buttonIcon.style.width = "100%";
- buttonIcon.style.height = "100%";
- button.onclick = callback;
-
- button.appendChild(buttonIcon);
-
- const children = Array.from(iconHolder.children);
- if (customIndex <= children.length) {
- iconHolder.insertBefore(button, children[customIndex - 1]);
- } else {
- iconHolder.appendChild(button);
- }
-
- buttonElementList.push(button);
- return button;
- }, 1000);
-}
-
-export function CleanupButtons() {
- Array.from(buttonElementList).forEach(element => {
- element.remove();
- });
-
- Array.from(document.getElementsByClassName("xcl_customButton")).forEach(element => {
- element.remove();
- });
-}
\ No newline at end of file
diff --git a/plugins/plugins/oled-theme/dist/index.js b/plugins/plugins/oled-theme/dist/index.js
deleted file mode 100644
index 1bfa53c..0000000
--- a/plugins/plugins/oled-theme/dist/index.js
+++ /dev/null
@@ -1 +0,0 @@
-var f=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var b=(t,e)=>()=>(t&&(e=t(t=0)),e);var R=(t,e)=>{for(var n in e)f(t,n,{get:e[n],enumerable:!0})},$=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of x(e))!S.call(t,r)&&r!==n&&f(t,r,{get:()=>e[r],enumerable:!(s=C(e,r))||s.enumerable});return t};var O=t=>$(f({},"__esModule",{value:!0}),t);var E={};R(E,{Tracer:()=>m,libTrace:()=>k});import{actions as h}from"@neptune";var m,k,g=b(()=>{"use strict";m=t=>{let e=c=>{let a=(...o)=>{c(t,...o)};return a.withContext=o=>(...d)=>{c(t,o,...d)},a},n=e(console.log),s=e(console.warn),r=e(console.error),w=e(console.debug),p=(c,a,o)=>{let d=i=>{c(i),a({message:`${t} - ${i}`,category:"OTHER",severity:o})};return d.withContext=i=>{let y=c.withContext(i);return l=>{y(l),l instanceof Error&&(l=l.message),a({message:`${t}.${i} - ${l}`,category:"OTHER",severity:o})}},d};return{log:n,warn:s,err:r,debug:w,msg:{log:p(n,h.message.messageInfo,"INFO"),warn:p(s,h.message.messageWarn,"WARN"),err:p(r,h.message.messageError,"ERROR")}}},k=m("[lib]")});g();import"@neptune";g();var N=m("[OLED Theme]"),H="https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/themes/black-neptune-theme.css",T,u;function L(t){let e=document.createElement("style");return e.type="text/css",e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t)),document.head.appendChild(e),e}function U(){u&&u.parentNode&&u.parentNode.removeChild(u)}async function v(t){try{let e=await fetch(t);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return await e.text()}catch(e){return N.msg.err(`Failed to fetch URL: ${e.message}`),null}}(async()=>(T=await v(H),u=L(T)))();function F(){U();let t=document.querySelector('div[class^="trackTitleContainer"]');t&&t.removeEventListener("DOMSubtreeModified",onTrackChanged)}export{F as onUnload};
diff --git a/plugins/plugins/oled-theme/dist/manifest.json b/plugins/plugins/oled-theme/dist/manifest.json
deleted file mode 100644
index 4be5198..0000000
--- a/plugins/plugins/oled-theme/dist/manifest.json
+++ /dev/null
@@ -1 +0,0 @@
-{"name":"Dark Abyss (OLED Theme)","description":"A working theme, ong.","author":"itzzexcel@github","hash":"6861f72cdfb2fdbd665f9d29c8fd52d9","metafile":{"inputs":{"plugins/oled-theme/src/tracer.js":{"bytes":1596,"imports":[{"path":"@neptune","kind":"import-statement","external":true}],"format":"esm"},"plugins/oled-theme/src/index.js":{"bytes":6921,"imports":[{"path":"plugins/oled-theme/src/tracer.js","kind":"import-statement","original":"./tracer"},{"path":"@neptune","kind":"import-statement","external":true},{"path":"plugins/oled-theme/src/tracer.js","kind":"require-call","original":"./tracer"}],"format":"esm"}},"outputs":{"plugins/oled-theme/dist/index.js":{"imports":[{"path":"@neptune","kind":"import-statement","external":true},{"path":"@neptune","kind":"import-statement","external":true}],"exports":["onUnload"],"entryPoint":"plugins/oled-theme/src/index.js","inputs":{"plugins/oled-theme/src/tracer.js":{"bytesInOutput":693},"plugins/oled-theme/src/index.js":{"bytesInOutput":785}},"bytes":1948}}}}
\ No newline at end of file
diff --git a/plugins/plugins/oled-theme/package.json b/plugins/plugins/oled-theme/package.json
deleted file mode 100644
index d020e40..0000000
--- a/plugins/plugins/oled-theme/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "canvas-confetti": "^1.6.0",
- "neptune-types": "1.0.1"
- }
-}
\ No newline at end of file
diff --git a/plugins/plugins/oled-theme/plugin.json b/plugins/plugins/oled-theme/plugin.json
deleted file mode 100644
index 31fe7f3..0000000
--- a/plugins/plugins/oled-theme/plugin.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "Dark Abyss (OLED Theme)",
- "description": "A working theme, ong.",
- "author": "itzzexcel@github",
- "main": "./src/index.js"
-}
\ No newline at end of file
diff --git a/plugins/plugins/oled-theme/pnpm-lock.yaml b/plugins/plugins/oled-theme/pnpm-lock.yaml
deleted file mode 100644
index 1d2e826..0000000
--- a/plugins/plugins/oled-theme/pnpm-lock.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-lockfileVersion: '6.1'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-dependencies:
- canvas-confetti:
- specifier: ^1.6.0
- version: 1.6.0
-
-packages:
-
- /canvas-confetti@1.6.0:
- resolution: {integrity: sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA==}
- dev: false
diff --git a/plugins/plugins/oled-theme/src/index.js b/plugins/plugins/oled-theme/src/index.js
deleted file mode 100644
index 46bc1fb..0000000
--- a/plugins/plugins/oled-theme/src/index.js
+++ /dev/null
@@ -1,189 +0,0 @@
-require("./tracer")
-import { Tracer } from "./tracer";
-import { intercept, store, utils } from "@neptune"
-
-const trace = Tracer("[OLED Theme]");
-const themeUrl = "https://raw.githubusercontent.com/ItzzExcel/neptune-projects/refs/heads/main/themes/black-neptune-theme.css";
-
-let style;
-let styleElement;
-
-// function observeTrackTitle() {
-// const trackTitleElement = document.querySelector('[class^="trackTitleContainer"]');
-// if (trackTitleElement) {
-// trackTitleElement.addEventListener('DOMSubtreeModified', () => {
-// setTimeout(() => {
-// // console.log("Track changed: " + trackTitleElement.querySelector("span").innerHTML + "\n")
-// onTrackChanged();
-// }, 300);
-// });
-// }
-// }
-
-function ApplyCSS(style) {
- const styleElement = document.createElement("style");
- styleElement.type = "text/css";
- if (styleElement.styleSheet) styleElement.styleSheet.cssText = style;
- else styleElement.appendChild(document.createTextNode(style));
-
- document.head.appendChild(styleElement);
- return styleElement;
-}
-
-function CleanUpCSS() {
- if (styleElement && styleElement.parentNode) {
- styleElement.parentNode.removeChild(styleElement);
- }
-}
-
-async function HttpGet(url) {
- try {
- const response = await fetch(url);
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
- const content = await response.text();
- return content;
- } catch (error) {
- trace.msg.err(`Failed to fetch URL: ${error.message}`);
- return null;
- }
-}
-
-// Since HttpGet is async, we need to await its result
-(async () => {
- style = await HttpGet(themeUrl);
- styleElement = ApplyCSS(style);
-})();
-
-// const onTrackChanged = function (method = 0) {
-// // Tu amor tan liminal, tu amor tan liminal
-// // - Ghouljaboy, 2021
-
-// if (method === 1) {
-// setTimeout(() => {
-// onTrackChanged();
-// return;
-// }, 2000);
-// }
-
-// let albumImageElement = document.querySelector('figure[class*="albumImage"] > div > div > div > img');
-// let albumImageSrc;
-
-// if (albumImageElement) {
-// albumImageSrc = albumImageElement.src;
-
-// // Set res to 1280x1280
-// albumImageSrc = albumImageSrc.replace(/\d+x\d+/, '1280x1280');
-// albumImageElement.src = albumImageSrc;
-// }
-
-// // Setting background to the *="nowPlayingContainer" element
-// let nowPlayingContainerElement = document.querySelector('[class*="nowPlayingContainer"]');
-// if (nowPlayingContainerElement && albumImageSrc) {
-// // Remove existing corner images if they exist
-// const existingImages = nowPlayingContainerElement.querySelectorAll('.corner-image');
-// existingImages.forEach(img => img.remove());
-
-// // Create and append center image
-// const centerImg = document.createElement('img');
-// centerImg.src = albumImageSrc;
-// centerImg.className = 'corner-image';
-// centerImg.style.position = 'absolute';
-// centerImg.style.left = '50%';
-// centerImg.style.top = '50%';
-// centerImg.style.transform = 'translate(-50%, -50%)';
-// centerImg.style.width = '75vw';
-// centerImg.style.height = '150vh';
-// centerImg.style.objectFit = 'cover';
-// centerImg.style.zIndex = '-1';
-// centerImg.style.filter = 'blur(100px) brightness(0.6) contrast(1.2) saturate(1)';
-// centerImg.style.animation = 'spin 35s linear infinite';
-// nowPlayingContainerElement.appendChild(centerImg);
-
-// const centerImg2 = document.createElement('img');
-// centerImg2.src = albumImageSrc;
-// centerImg2.className = 'corner-image';
-// centerImg2.style.position = 'absolute';
-// centerImg2.style.left = '50%';
-// centerImg2.style.top = '50%';
-// centerImg2.style.transform = 'translate(-50%, -50%)';
-// centerImg2.style.width = '75vw';
-// centerImg2.style.height = '150vh';
-// centerImg2.style.objectFit = 'cover';
-// centerImg2.style.zIndex = '-1';
-// centerImg2.style.filter = 'blur(100px) brightness(0.6) contrast(1.2) saturate(1)';
-// centerImg2.style.animation = 'spin 35s linear infinite';
-// nowPlayingContainerElement.appendChild(centerImg2);
-
-// // Add keyframe animation if it doesn't exist
-// if (!document.querySelector('#spinAnimation')) {
-// const styleSheet = document.createElement('style');
-// styleSheet.id = 'spinAnimation';
-// styleSheet.textContent = `
-// @keyframes spin {
-// from { transform: translate(-50%, -50%) rotate(0deg); }
-// to { transform: translate(-50%, -50%) rotate(360deg); }
-// }
-// `;
-// document.head.appendChild(styleSheet);
-// }
-// }
-// };
-
-// const spinElement = function(elementToSpin) {
-// elementToSpin.style.animation = "spin 35s linear infinite";
-// };
-
-// const resumeSpinAnimation = function(elementToResume) {
-// elementToResume.style.animationPlayState = "running";
-// };
-
-// const pauseSpinAnimation = function(elementToPause) {
-// elementToPause.style.animationPlayState = "paused";
-// };
-
-// const cleanUpDynamicArt = function () {
-// [...document.getElementsByClassName("corner-image")].forEach((element) => {
-// element.remove();
-// });
-// };
-
-// const onTrackPaused = function ([track]) {
-// [...document.getElementsByClassName("corner-image")].forEach((element) => {
-// element.style.animation = "spin 50s linear infinite";
-// });
-// }
-
-// const onTrackResumed = function ([track]) {
-// [...document.getElementsByClassName("corner-image")].forEach((element) => {
-// element.style.animation = "spin 20s linear infinite";
-// });
-// }
-// const PLAYBACK_EVENTS = [
-// "playbackControls/PREFILL_MEDIA_PRODUCT_TRANSITION",
-// "playbackControls/MEDIA_PRODUCT_TRANSITION"
-// ];
-
-// observeTrackTitle();
-// observeTrackTitle();
-// observeTrackTitle();
-// observeTrackTitle();
-
-// const unsubscribeFunctions = PLAYBACK_EVENTS.map(event =>
-// intercept(event, () => {
-// onTrackChanged(1);
-// })
-// );
-
-
-export function onUnload() {
- CleanUpCSS();
- // unsubscribeFunctions.forEach(unsubscribe => unsubscribe());
- // cleanUpDynamicArt();
-
- const trackTitleElement = document.querySelector('div[class^="trackTitleContainer"]');
- if (trackTitleElement) {
- trackTitleElement.removeEventListener('DOMSubtreeModified', onTrackChanged);
- }
-}
\ No newline at end of file
diff --git a/plugins/plugins/oled-theme/src/tracer.js b/plugins/plugins/oled-theme/src/tracer.js
deleted file mode 100644
index f18bcd3..0000000
--- a/plugins/plugins/oled-theme/src/tracer.js
+++ /dev/null
@@ -1,55 +0,0 @@
-// Based on https://github.com/Inrixia/neptune-plugins/blob/3d28c9ea3252782da830698032dbb49dbe5b9fd6/plugins/_lib/trace.ts
-// Credits to inrixia
-
-import { actions } from "@neptune";
-
-export const Tracer = (source) => {
- const createLogger = (logger) => {
- const _logger = (...data) => {
- logger(source, ...data);
- return undefined;
- };
- _logger.withContext = (context) => (...data) => {
- logger(source, context, ...data);
- return undefined;
- };
- return _logger;
- };
-
- const log = createLogger(console.log);
- const warn = createLogger(console.warn);
- const err = createLogger(console.error);
- const debug = createLogger(console.debug);
-
- const createMessager = (logger, messager, severity) => {
- const _messager = (message) => {
- logger(message);
- messager({ message: `${source} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- _messager.withContext = (context) => {
- const loggerWithContext = logger.withContext(context);
- return (message) => {
- loggerWithContext(message);
- if (message instanceof Error) message = message.message;
- messager({ message: `${source}.${context} - ${message}`, category: "OTHER", severity });
- return undefined;
- };
- };
- return _messager;
- };
-
- return {
- log,
- warn,
- err,
- debug,
- msg: {
- log: createMessager(log, actions.message.messageInfo, "INFO"),
- warn: createMessager(warn, actions.message.messageWarn, "WARN"),
- err: createMessager(err, actions.message.messageError, "ERROR"),
- },
- };
-};
-
-export const libTrace = Tracer("[lib]");
\ No newline at end of file
diff --git a/plugins/pnpm-lock.yaml b/plugins/pnpm-lock.yaml
deleted file mode 100644
index 6613473..0000000
--- a/plugins/pnpm-lock.yaml
+++ /dev/null
@@ -1,308 +0,0 @@
-lockfileVersion: '6.1'
-
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
-devDependencies:
- esbuild:
- specifier: ^0.18.13
- version: 0.18.13
- neptune-types:
- specifier: ^1.0.0
- version: 1.0.0
-
-packages:
-
- /@babel/runtime@7.22.15:
- resolution: {integrity: sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- regenerator-runtime: 0.14.0
- dev: true
-
- /@esbuild/android-arm64@0.18.13:
- resolution: {integrity: sha512-j7NhycJUoUAG5kAzGf4fPWfd17N6SM3o1X6MlXVqfHvs2buFraCJzos9vbeWjLxOyBKHyPOnuCuipbhvbYtTAg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/android-arm@0.18.13:
- resolution: {integrity: sha512-KwqFhxRFMKZINHzCqf8eKxE0XqWlAVPRxwy6rc7CbVFxzUWB2sA/s3hbMZeemPdhN3fKBkqOaFhTbS8xJXYIWQ==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/android-x64@0.18.13:
- resolution: {integrity: sha512-M2eZkRxR6WnWfVELHmv6MUoHbOqnzoTVSIxgtsyhm/NsgmL+uTmag/VVzdXvmahak1I6sOb1K/2movco5ikDJg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/darwin-arm64@0.18.13:
- resolution: {integrity: sha512-f5goG30YgR1GU+fxtaBRdSW3SBG9pZW834Mmhxa6terzcboz7P2R0k4lDxlkP7NYRIIdBbWp+VgwQbmMH4yV7w==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/darwin-x64@0.18.13:
- resolution: {integrity: sha512-RIrxoKH5Eo+yE5BtaAIMZaiKutPhZjw+j0OCh8WdvKEKJQteacq0myZvBDLU+hOzQOZWJeDnuQ2xgSScKf1Ovw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/freebsd-arm64@0.18.13:
- resolution: {integrity: sha512-AfRPhHWmj9jGyLgW/2FkYERKmYR+IjYxf2rtSLmhOrPGFh0KCETFzSjx/JX/HJnvIqHt/DRQD/KAaVsUKoI3Xg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/freebsd-x64@0.18.13:
- resolution: {integrity: sha512-pGzWWZJBInhIgdEwzn8VHUBang8UvFKsvjDkeJ2oyY5gZtAM6BaxK0QLCuZY+qoj/nx/lIaItH425rm/hloETA==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-arm64@0.18.13:
- resolution: {integrity: sha512-hCzZbVJEHV7QM77fHPv2qgBcWxgglGFGCxk6KfQx6PsVIdi1u09X7IvgE9QKqm38OpkzaAkPnnPqwRsltvLkIQ==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-arm@0.18.13:
- resolution: {integrity: sha512-4iMxLRMCxGyk7lEvkkvrxw4aJeC93YIIrfbBlUJ062kilUUnAiMb81eEkVvCVoh3ON283ans7+OQkuy1uHW+Hw==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-ia32@0.18.13:
- resolution: {integrity: sha512-I3OKGbynl3AAIO6onXNrup/ttToE6Rv2XYfFgLK/wnr2J+1g+7k4asLrE+n7VMhaqX+BUnyWkCu27rl+62Adug==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-loong64@0.18.13:
- resolution: {integrity: sha512-8pcKDApAsKc6WW51ZEVidSGwGbebYw2qKnO1VyD8xd6JN0RN6EUXfhXmDk9Vc4/U3Y4AoFTexQewQDJGsBXBpg==}
- engines: {node: '>=12'}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-mips64el@0.18.13:
- resolution: {integrity: sha512-6GU+J1PLiVqWx8yoCK4Z0GnfKyCGIH5L2KQipxOtbNPBs+qNDcMJr9euxnyJ6FkRPyMwaSkjejzPSISD9hb+gg==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-ppc64@0.18.13:
- resolution: {integrity: sha512-pfn/OGZ8tyR8YCV7MlLl5hAit2cmS+j/ZZg9DdH0uxdCoJpV7+5DbuXrR+es4ayRVKIcfS9TTMCs60vqQDmh+w==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-riscv64@0.18.13:
- resolution: {integrity: sha512-aIbhU3LPg0lOSCfVeGHbmGYIqOtW6+yzO+Nfv57YblEK01oj0mFMtvDJlOaeAZ6z0FZ9D13oahi5aIl9JFphGg==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-s390x@0.18.13:
- resolution: {integrity: sha512-Pct1QwF2sp+5LVi4Iu5Y+6JsGaV2Z2vm4O9Dd7XZ5tKYxEHjFtb140fiMcl5HM1iuv6xXO8O1Vrb1iJxHlv8UA==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/linux-x64@0.18.13:
- resolution: {integrity: sha512-zTrIP0KzYP7O0+3ZnmzvUKgGtUvf4+piY8PIO3V8/GfmVd3ZyHJGz7Ht0np3P1wz+I8qJ4rjwJKqqEAbIEPngA==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/netbsd-x64@0.18.13:
- resolution: {integrity: sha512-I6zs10TZeaHDYoGxENuksxE1sxqZpCp+agYeW039yqFwh3MgVvdmXL5NMveImOC6AtpLvE4xG5ujVic4NWFIDQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/openbsd-x64@0.18.13:
- resolution: {integrity: sha512-W5C5nczhrt1y1xPG5bV+0M12p2vetOGlvs43LH8SopQ3z2AseIROu09VgRqydx5qFN7y9qCbpgHLx0kb0TcW7g==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/sunos-x64@0.18.13:
- resolution: {integrity: sha512-X/xzuw4Hzpo/yq3YsfBbIsipNgmsm8mE/QeWbdGdTTeZ77fjxI2K0KP3AlhZ6gU3zKTw1bKoZTuKLnqcJ537qw==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/win32-arm64@0.18.13:
- resolution: {integrity: sha512-4CGYdRQT/ILd+yLLE5i4VApMPfGE0RPc/wFQhlluDQCK09+b4JDbxzzjpgQqTPrdnP7r5KUtGVGZYclYiPuHrw==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/win32-ia32@0.18.13:
- resolution: {integrity: sha512-D+wKZaRhQI+MUGMH+DbEr4owC2D7XnF+uyGiZk38QbgzLcofFqIOwFs7ELmIeU45CQgfHNy9Q+LKW3cE8g37Kg==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/win32-x64@0.18.13:
- resolution: {integrity: sha512-iVl6lehAfJS+VmpF3exKpNQ8b0eucf5VWfzR8S7xFve64NBNz2jPUgx1X93/kfnkfgP737O+i1k54SVQS7uVZA==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /esbuild@0.18.13:
- resolution: {integrity: sha512-vhg/WR/Oiu4oUIkVhmfcc23G6/zWuEQKFS+yiosSHe4aN6+DQRXIfeloYGibIfVhkr4wyfuVsGNLr+sQU1rWWw==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/android-arm': 0.18.13
- '@esbuild/android-arm64': 0.18.13
- '@esbuild/android-x64': 0.18.13
- '@esbuild/darwin-arm64': 0.18.13
- '@esbuild/darwin-x64': 0.18.13
- '@esbuild/freebsd-arm64': 0.18.13
- '@esbuild/freebsd-x64': 0.18.13
- '@esbuild/linux-arm': 0.18.13
- '@esbuild/linux-arm64': 0.18.13
- '@esbuild/linux-ia32': 0.18.13
- '@esbuild/linux-loong64': 0.18.13
- '@esbuild/linux-mips64el': 0.18.13
- '@esbuild/linux-ppc64': 0.18.13
- '@esbuild/linux-riscv64': 0.18.13
- '@esbuild/linux-s390x': 0.18.13
- '@esbuild/linux-x64': 0.18.13
- '@esbuild/netbsd-x64': 0.18.13
- '@esbuild/openbsd-x64': 0.18.13
- '@esbuild/sunos-x64': 0.18.13
- '@esbuild/win32-arm64': 0.18.13
- '@esbuild/win32-ia32': 0.18.13
- '@esbuild/win32-x64': 0.18.13
- dev: true
-
- /htm@3.1.1:
- resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==}
- dev: true
-
- /idb-keyval@6.2.1:
- resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==}
- dev: true
-
- /immutable@5.0.0-beta.4:
- resolution: {integrity: sha512-sl9RE3lqd2LoQSESc8VV0k8qE9y57iT7dinq3Q+8mR2dqReHDZlgUrudzmFfZhDXBLXlNJMVWv3SG1YpQIokig==}
- dev: true
-
- /neptune-types@1.0.0:
- resolution: {integrity: sha512-ulXxp5m7lup2fR3ppdnHQBXPrvwLmBK54Npfded2pYhK5SGrlbIlpcNUPkT5aqsbZhjOVaRZY4BWoFt5LGI+cQ==}
- dependencies:
- idb-keyval: 6.2.1
- immutable: 5.0.0-beta.4
- redux: 4.2.1
- spitroast: 1.4.3
- type-fest: 4.3.1
- voby: 0.54.0
- zod: 3.22.2
- dev: true
-
- /oby@14.3.1:
- resolution: {integrity: sha512-/5BvIarE2epsV2DDjcBf6R7DvcoUqtU62AOEEQyUqaKzwz0kdpB6huOG8anaqU0Asa9UGPFxdQWVbUPpEGLkuw==}
- dev: true
-
- /redux@4.2.1:
- resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
- dependencies:
- '@babel/runtime': 7.22.15
- dev: true
-
- /regenerator-runtime@0.14.0:
- resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
- dev: true
-
- /spitroast@1.4.3:
- resolution: {integrity: sha512-JdkzAy2tT82ahx+eEtM5ohBeHICqFln/Yzo+vPGnE5sX1LYgPHCU2qcaSIJfR/xNrhI0q+ftwFz0H2aJysv3EA==}
- dev: true
-
- /type-fest@4.3.1:
- resolution: {integrity: sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw==}
- engines: {node: '>=16'}
- dev: true
-
- /voby@0.54.0:
- resolution: {integrity: sha512-hH8LXcP0QR4J6nnzfSWGD13onq7hqdc/ya1r1Bb+TxibtECYKZRO1m4HdSU4RcE7MdAaQwR5pwgd+hqXCqk2OA==}
- dependencies:
- htm: 3.1.1
- oby: 14.3.1
- dev: true
-
- /zod@3.22.2:
- resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==}
- dev: true
diff --git a/plugins/tsconfig.json b/plugins/tsconfig.json
deleted file mode 100644
index 78ff269..0000000
--- a/plugins/tsconfig.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "neptune-types/tsconfig.base.json"
-}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..6453a45
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,1334 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@types/node':
+ specifier: ^22.15.29
+ version: 22.15.29
+ '@types/react':
+ specifier: ^19.1.6
+ version: 19.1.6
+ '@types/react-dom':
+ specifier: ^19.1.5
+ version: 19.1.5(@types/react@19.1.6)
+ concurrently:
+ specifier: ^9.1.2
+ version: 9.1.2
+ http-server:
+ specifier: ^14.1.1
+ version: 14.1.1
+ luna:
+ specifier: github:Inrixia/TidaLuna#81369c7
+ version: https://codeload.github.com/Inrixia/TidaLuna/tar.gz/81369c7
+ oby:
+ specifier: ^15.1.2
+ version: 15.1.2
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
+ tsx:
+ specifier: ^4.19.4
+ version: 4.19.4
+ typescript:
+ specifier: ^5.8.3
+ version: 5.8.3
+
+ plugins/oled-theme-luna: {}
+
+packages:
+
+ '@esbuild/aix-ppc64@0.25.5':
+ resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.5':
+ resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.5':
+ resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.5':
+ resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.5':
+ resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.5':
+ resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.5':
+ resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.5':
+ resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.5':
+ resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.5':
+ resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.5':
+ resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.5':
+ resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.5':
+ resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.5':
+ resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.5':
+ resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.5':
+ resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.5':
+ resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.5':
+ resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.5':
+ resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.5':
+ resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.5':
+ resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.25.5':
+ resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.5':
+ resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.5':
+ resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.5':
+ resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@inrixia/helpers@3.20.0':
+ resolution: {integrity: sha512-RkWZ8ZIdB3cpQvTcLsY3A8ux+4Q8PNZU0uDKJT2xVMAP0FvCsLNSJemRz9vlDalWBDkBhI9v0O/br3cF9vPnWw==}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/gen-mapping@0.3.8':
+ resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/source-map@0.3.6':
+ resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@types/clean-css@4.2.11':
+ resolution: {integrity: sha512-Y8n81lQVTAfP2TOdtJJEsCoYl1AnOkqDqMvXb9/7pfgZZ7r8YrEyurrAvAoAjHOGXKRybay+5CsExqIH6liccw==}
+
+ '@types/html-minifier-terser@7.0.2':
+ resolution: {integrity: sha512-mm2HqV22l8lFQh4r2oSsOEVea+m0qqxEmwpc9kC1p/XzmjLWrReR9D/GRs8Pex2NX/imyEH9c5IU/7tMBQCHOA==}
+
+ '@types/node@22.15.29':
+ resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==}
+
+ '@types/react-dom@19.1.5':
+ resolution: {integrity: sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==}
+ peerDependencies:
+ '@types/react': ^19.0.0
+
+ '@types/react@19.1.6':
+ resolution: {integrity: sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==}
+
+ acorn@8.14.1:
+ resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ async@3.2.6:
+ resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ basic-auth@2.0.1:
+ resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
+ engines: {node: '>= 0.8'}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
+ camel-case@4.1.2:
+ resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ clean-css@5.3.3:
+ resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
+ engines: {node: '>= 10.0'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ commander@10.0.1:
+ resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
+ engines: {node: '>=14'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ concurrently@9.1.2:
+ resolution: {integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ corser@2.0.1:
+ resolution: {integrity: sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==}
+ engines: {node: '>= 0.4.0'}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.4.1:
+ resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ dot-case@3.0.4:
+ resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.1:
+ resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.25.5:
+ resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ eventemitter3@4.0.7:
+ resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
+
+ follow-redirects@1.15.9:
+ resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ get-tsconfig@4.10.1:
+ resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
+
+ glob@11.0.2:
+ resolution: {integrity: sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ html-encoding-sniffer@3.0.0:
+ resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==}
+ engines: {node: '>=12'}
+
+ html-minifier-terser@7.2.0:
+ resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==}
+ engines: {node: ^14.13.1 || >=16.0.0}
+ hasBin: true
+
+ http-proxy@1.18.1:
+ resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
+ engines: {node: '>=8.0.0'}
+
+ http-server@14.1.1:
+ resolution: {integrity: sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jackspeak@4.1.1:
+ resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
+ engines: {node: 20 || >=22}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ lower-case@2.0.2:
+ resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+
+ lru-cache@11.1.0:
+ resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==}
+ engines: {node: 20 || >=22}
+
+ luna@https://codeload.github.com/Inrixia/TidaLuna/tar.gz/81369c7:
+ resolution: {tarball: https://codeload.github.com/Inrixia/TidaLuna/tar.gz/81369c7}
+ version: 1.5.1-beta
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ no-case@3.0.4:
+ resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ oby@15.1.2:
+ resolution: {integrity: sha512-6QD9iEoPzV+pMDdcg3RtFWhgDX8pS5hZouVHvgXGDy3Q9RxFfnI3CYv9i62keeuX+qk6iN2z5E9FD3q3OckZ6A==}
+
+ opener@1.5.2:
+ resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
+ hasBin: true
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ param-case@3.0.4:
+ resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
+
+ pascal-case@3.1.2:
+ resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ portfinder@1.0.37:
+ resolution: {integrity: sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==}
+ engines: {node: '>= 10.12'}
+
+ qs@6.14.0:
+ resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
+ engines: {node: '>=0.6'}
+
+ relateurl@0.2.7:
+ resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
+ engines: {node: '>= 0.10'}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ requires-port@1.0.0:
+ resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ rxjs@7.8.2:
+ resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
+
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ secure-compare@3.0.1:
+ resolution: {integrity: sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ shell-quote@1.8.2:
+ resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-list@1.0.0:
+ resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.0:
+ resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
+ engines: {node: '>= 0.4'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
+ terser@5.40.0:
+ resolution: {integrity: sha512-cfeKl/jjwSR5ar7d0FGmave9hFGJT8obyo0z+CrQOylLDbk7X81nPU6vq9VORa5jU30SkDnT2FXjLbR8HLP+xA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsx@4.19.4:
+ resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ typescript@5.8.3:
+ resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ union@0.5.0:
+ resolution: {integrity: sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==}
+ engines: {node: '>= 0.8.0'}
+
+ url-join@4.0.1:
+ resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
+
+ whatwg-encoding@2.0.0:
+ resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
+ engines: {node: '>=12'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+snapshots:
+
+ '@esbuild/aix-ppc64@0.25.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/android-arm@0.25.5':
+ optional: true
+
+ '@esbuild/android-x64@0.25.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.25.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.25.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.25.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.25.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.25.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.25.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.25.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.25.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.25.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.25.5':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.25.5':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.25.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.25.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.25.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.25.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.5':
+ optional: true
+
+ '@inrixia/helpers@3.20.0':
+ dependencies:
+ dequal: 2.0.3
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jridgewell/gen-mapping@0.3.8':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/source-map@0.3.6':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.8
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@types/clean-css@4.2.11':
+ dependencies:
+ '@types/node': 22.15.29
+ source-map: 0.6.1
+
+ '@types/html-minifier-terser@7.0.2': {}
+
+ '@types/node@22.15.29':
+ dependencies:
+ undici-types: 6.21.0
+
+ '@types/react-dom@19.1.5(@types/react@19.1.6)':
+ dependencies:
+ '@types/react': 19.1.6
+
+ '@types/react@19.1.6':
+ dependencies:
+ csstype: 3.1.3
+
+ acorn@8.14.1: {}
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.1.0: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@6.2.1: {}
+
+ async@3.2.6: {}
+
+ balanced-match@1.0.2: {}
+
+ basic-auth@2.0.1:
+ dependencies:
+ safe-buffer: 5.1.2
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ buffer-from@1.1.2: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
+ camel-case@4.1.2:
+ dependencies:
+ pascal-case: 3.1.2
+ tslib: 2.8.1
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ clean-css@5.3.3:
+ dependencies:
+ source-map: 0.6.1
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ commander@10.0.1: {}
+
+ commander@2.20.3: {}
+
+ concurrently@9.1.2:
+ dependencies:
+ chalk: 4.1.2
+ lodash: 4.17.21
+ rxjs: 7.8.2
+ shell-quote: 1.8.2
+ supports-color: 8.1.1
+ tree-kill: 1.2.2
+ yargs: 17.7.2
+
+ corser@2.0.1: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ csstype@3.1.3: {}
+
+ debug@4.4.1:
+ dependencies:
+ ms: 2.1.3
+
+ dequal@2.0.3: {}
+
+ dot-case@3.0.4:
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.8.1
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ eastasianwidth@0.2.0: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ entities@4.5.0: {}
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-object-atoms@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+
+ esbuild@0.25.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.5
+ '@esbuild/android-arm': 0.25.5
+ '@esbuild/android-arm64': 0.25.5
+ '@esbuild/android-x64': 0.25.5
+ '@esbuild/darwin-arm64': 0.25.5
+ '@esbuild/darwin-x64': 0.25.5
+ '@esbuild/freebsd-arm64': 0.25.5
+ '@esbuild/freebsd-x64': 0.25.5
+ '@esbuild/linux-arm': 0.25.5
+ '@esbuild/linux-arm64': 0.25.5
+ '@esbuild/linux-ia32': 0.25.5
+ '@esbuild/linux-loong64': 0.25.5
+ '@esbuild/linux-mips64el': 0.25.5
+ '@esbuild/linux-ppc64': 0.25.5
+ '@esbuild/linux-riscv64': 0.25.5
+ '@esbuild/linux-s390x': 0.25.5
+ '@esbuild/linux-x64': 0.25.5
+ '@esbuild/netbsd-arm64': 0.25.5
+ '@esbuild/netbsd-x64': 0.25.5
+ '@esbuild/openbsd-arm64': 0.25.5
+ '@esbuild/openbsd-x64': 0.25.5
+ '@esbuild/sunos-x64': 0.25.5
+ '@esbuild/win32-arm64': 0.25.5
+ '@esbuild/win32-ia32': 0.25.5
+ '@esbuild/win32-x64': 0.25.5
+
+ escalade@3.2.0: {}
+
+ eventemitter3@4.0.7: {}
+
+ follow-redirects@1.15.9: {}
+
+ foreground-child@3.3.1:
+ dependencies:
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-caller-file@2.0.5: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.1
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.1
+
+ get-tsconfig@4.10.1:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ glob@11.0.2:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 4.1.1
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
+ gopd@1.2.0: {}
+
+ has-flag@4.0.0: {}
+
+ has-symbols@1.1.0: {}
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ he@1.2.0: {}
+
+ html-encoding-sniffer@3.0.0:
+ dependencies:
+ whatwg-encoding: 2.0.0
+
+ html-minifier-terser@7.2.0:
+ dependencies:
+ camel-case: 4.1.2
+ clean-css: 5.3.3
+ commander: 10.0.1
+ entities: 4.5.0
+ param-case: 3.0.4
+ relateurl: 0.2.7
+ terser: 5.40.0
+
+ http-proxy@1.18.1:
+ dependencies:
+ eventemitter3: 4.0.7
+ follow-redirects: 1.15.9
+ requires-port: 1.0.0
+ transitivePeerDependencies:
+ - debug
+
+ http-server@14.1.1:
+ dependencies:
+ basic-auth: 2.0.1
+ chalk: 4.1.2
+ corser: 2.0.1
+ he: 1.2.0
+ html-encoding-sniffer: 3.0.0
+ http-proxy: 1.18.1
+ mime: 1.6.0
+ minimist: 1.2.8
+ opener: 1.5.2
+ portfinder: 1.0.37
+ secure-compare: 3.0.1
+ union: 0.5.0
+ url-join: 4.0.1
+ transitivePeerDependencies:
+ - debug
+ - supports-color
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ isexe@2.0.0: {}
+
+ jackspeak@4.1.1:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
+ lodash@4.17.21: {}
+
+ lower-case@2.0.2:
+ dependencies:
+ tslib: 2.8.1
+
+ lru-cache@11.1.0: {}
+
+ luna@https://codeload.github.com/Inrixia/TidaLuna/tar.gz/81369c7:
+ dependencies:
+ '@inrixia/helpers': 3.20.0
+ '@types/clean-css': 4.2.11
+ '@types/html-minifier-terser': 7.0.2
+ '@types/node': 22.15.29
+ clean-css: 5.3.3
+ esbuild: 0.25.5
+ html-minifier-terser: 7.2.0
+
+ math-intrinsics@1.1.0: {}
+
+ mime@1.6.0: {}
+
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimist@1.2.8: {}
+
+ minipass@7.1.2: {}
+
+ ms@2.1.3: {}
+
+ no-case@3.0.4:
+ dependencies:
+ lower-case: 2.0.2
+ tslib: 2.8.1
+
+ object-inspect@1.13.4: {}
+
+ oby@15.1.2: {}
+
+ opener@1.5.2: {}
+
+ package-json-from-dist@1.0.1: {}
+
+ param-case@3.0.4:
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.8.1
+
+ pascal-case@3.1.2:
+ dependencies:
+ no-case: 3.0.4
+ tslib: 2.8.1
+
+ path-key@3.1.1: {}
+
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.1.0
+ minipass: 7.1.2
+
+ portfinder@1.0.37:
+ dependencies:
+ async: 3.2.6
+ debug: 4.4.1
+ transitivePeerDependencies:
+ - supports-color
+
+ qs@6.14.0:
+ dependencies:
+ side-channel: 1.1.0
+
+ relateurl@0.2.7: {}
+
+ require-directory@2.1.1: {}
+
+ requires-port@1.0.0: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.2
+ package-json-from-dist: 1.0.1
+
+ rxjs@7.8.2:
+ dependencies:
+ tslib: 2.8.1
+
+ safe-buffer@5.1.2: {}
+
+ safer-buffer@2.1.2: {}
+
+ secure-compare@3.0.1: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ shell-quote@1.8.2: {}
+
+ side-channel-list@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.0
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
+ signal-exit@4.1.0: {}
+
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
+ terser@5.40.0:
+ dependencies:
+ '@jridgewell/source-map': 0.3.6
+ acorn: 8.14.1
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ tree-kill@1.2.2: {}
+
+ tslib@2.8.1: {}
+
+ tsx@4.19.4:
+ dependencies:
+ esbuild: 0.25.5
+ get-tsconfig: 4.10.1
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ typescript@5.8.3: {}
+
+ undici-types@6.21.0: {}
+
+ union@0.5.0:
+ dependencies:
+ qs: 6.14.0
+
+ url-join@4.0.1: {}
+
+ whatwg-encoding@2.0.0:
+ dependencies:
+ iconv-lite: 0.6.3
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ y18n@5.0.8: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..f06af05
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,2 @@
+packages:
+ - "plugins/*"
diff --git a/themes/macos-black-variant.css b/themes/macos-black-variant.css
deleted file mode 100644
index 6d78c20..0000000
--- a/themes/macos-black-variant.css
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
-{
- "name": "Abyss Neptune",
- "author": "@itzzexcel",
- "description": "Abyss Neptune: ShadowX Theme from Spicetify to TIDAL (17/Jan/2025)"
-}
-*/
-
-::-webkit-scrollbar {
- display: none;
-}
-
-:root {
- --wave-color-solid-accent-fill: white;
- --wave-color-solid-rainbow-yellow-fill: white;
- --wave-color-solid-contrast-fill: white;
- --wave-color-solid-base-fill: rgb(25, 25, 25);
- --wave-color-solid-base-brighter: var(--wave-color-solid-base-fill);
- --wave-text-body-medium: white !important;
- --track-vibrant-color: white !important;
- --wave-color-opacity-contrast-fill-ultra-thin: #fffafa1a !important;
- --wave-color-solid-rainbow-yellow-darkest: #fffafa1a !important;
- --wave-color-solid-accent-dark: rgb(128, 128, 128);
-}
-
-/* Credits to https://github.com/surfbryce for the fonts */
-@font-face {
- font-family: "AbyssFont";
- font-weight: 400;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsRegular.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 500;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsMedium.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 600;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsSemibold.woff2") format("woff2");
-}
-
-@font-face {
- font-family: "AbyssFont";
- font-weight: 700;
- src: url("https://excel.lexploits.top/extra/tidal/LyricsBold.woff2") format("woff2");
-}
-
-[class^="followingButton"],
-[title="Unfollow"],
-[title="Follow"],
-[title="Unfollow"]>span,
-[title="Follow"]>span {
- background-color: var(--wave-color-solid-rainbow-yellow-fill) !important;
- color: var(--wave-color-solid-base-brighter);
-}
-
-[class^="_wave-badge-color-max"] {
- color: black !important;
- background-color: var(--wave-color-solid-accent-fill);
- border-radius: 3px;
-}
-
-[data-test="main-layout-sidebar-wrapper"] {
- border-right: var(--wave-color-opacity-contrast-fill-ultra-thin) 1px solid;
-}
-
-[class^="_wave-badge"] {
- background-color: var(--wave-color-solid-accent-fill);
- border-radius: 4px;
- color: black;
-}
-
-[class^="_progressBarWrapper"] {
- color: var(--wave-color-solid-accent-fill) !important;
-}
-
-[class^="_sidebarItem"]>span {
- color: var(--wave-color-solid-accent-dark);
-}
-
-[class^="_sidebarItem"]:hover span {
- color: var(--wave-color-solid-contrast-fill);
-}
-
-[class^="_sidebarItem"] [class^="active"]>span {
- color: var(--wave-color-solid-accent-dark) !important;
-}
-
-[class^="_active"] {
- color: var(--wave-color-solid-accent-fill) !important;
-}
-
-[class^="ReactVirtualized__Grid"] {
- border-radius: 10px;
- margin: 5px;
-}
-
-[data-test="media-table"]>div>div>div {
- border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
-}
-
-[class^="ReactVirtualized__Grid__innerScrollContainer"] {
- border: none;
- margin: 5px;
-}
-
-[class^="button"]>span {
- color: black;
-}
-
-[class^="_explicitBadge"] {
- color: var(--wave-color-solid-accent-fill);
-}
-
-[class^="viewAllButton"] {
- border-radius: 4px;
- display: grid;
- place-items: center;
-}
-
-[data-test="current-media-imagery"] {
- border: 0 !important;
- margin: none;
-}
-
-[class^="_imageBorder"] {
- display: none;
-}
-
-[class^="_headerButtons"]>button,
-[class^="_headerButtons"]>button>span,
-[data-test="toggle-picture-in-picture"] {
- background-color: var(--wave-color-solid-accent-fill) !important;
- color: black;
-}
-
-[class^="_buttons"]>button>span {
- color: black !important;
-}
-
-[class^="_container"]>button {
- border: 0px none;
-}
-
-[data-test="feed-sidebar"] {
- margin-top: 10px;
-}
-
-[data-test="footer-player"] {
- width: calc(100% - 20px);
- bottom: 10px;
- left: 10px;
- border: 1px solid var(--wave-color-solid-base-fill);
- border-radius: 4px !important;
- position: absolute !important;
-}
-
-[class^="_tooltipContainer"]>button {
- background-color: var(--wave-color-solid-accent-fill);
- color: black;
-}
-
-[class^="_tooltipContainer"]>button:hover {
- background-color: lightgray !important;
-}
-
-[class^="_tableRow"]:hover>*,
-[data-test-is-playing="true"]>* {
- color: var(--wave-color-solid-accent-fill) !important;
-}
-
-[class^="_tableRow"]>*,
-[data-test-is-playing="false"]>* {
- color: lightgray !important;
-}
-
-[class*="coverColumn"] {
- padding-left: 5px !important;
-}
-
-[class^="actionList"] {
- background-color: transparent;
- margin: 0px;
- border-radius: 5px;
-}
-
-button[data-test="request-fullscreen"],
-button[data-test="close-now-playing"],
-button[data-test="play-all"],
-button[data-test="shuffle-all"] {
- color: black;
- background-color: var(--wave-color-solid-accent-fill);
- border-radius: 12px;
-}
-
-button[data-test="request-fullscreen"]:hover,
-button[data-test="close-now-playing"]:hover {
- color: black;
- background-color: lightgray !important;
-}
-
-.neptune-switch-checkbox:checked+.neptune-switch {
- background-color: rgba(255, 255, 255, 0.1);
-}
-
-[data-test="navigation-arrows"]>button {
- color: whreite;
- background-color: rgb(50, 50, 50) !important;
- backdrop-filter: blur(10px);
- border-radius: 4px;
-}
-
-[data-test="navigation-arrows"]>button:disabled {
- background-color: rgb(40, 40, 40) !important;
- opacity: 1;
-}
-
-[data-test="main-layout-header"],
-[data-test="feed-sidebar"],
-[data-test="stream-metadata"],
-[data-test="footer-player"] {
- background-color: rgba(25, 25, 25, 0.8) !important;
- backdrop-filter: blur(10px);
- border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
-}
-
-[data-test="main-layout-header"] {
- border-left: 0 !important;
-}
-
-[data-wave-color=textUrl] {
- color: var(--wave-color-solid-accent-fill);
-}
-
-[class^="_smallHeader"] {
- margin-top: 7.5px;
-}
-
-[data-test="play-all"]>div>*,
-[data-test="shuffle-all"]>div>*,
-[data-test="play-all"],
-[data-test="shuffle-all"] {
- color: var(--wave-color-solid-accent-fill) !important;
- background-color: transparent !important;
-}
-
-[class^="__NEPTUNE_PAGE"],
-[data-test="main"] {
- margin-top: 35px;
-}
-
-[data-test="button-desktop-release-notes"],
-[data-test="button-release-notes"] {
- background-color: white;
-}
-
-[data-test="button-desktop-release-notes"]:hover,
-[data-test="button-release-notes"]:hover {
- background-color: lightgray !important;
- transition: none !important;
-}
-
-#playQueueSidebar {
- top: 50px !important;
- border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin);
- margin: 2px;
- margin-right: -14px !important;
- background-color: rgba(25, 25, 25, 0.8) !important;
- backdrop-filter: blur(10px);
-}
-
-[class^="_bottomGradient"] {
- visibility: hidden;
-}
-
-[data-test="settings-page"] {
- padding-bottom: 60px !important;
-}
-
-[data-test="query-suggestions"],
-[data-test="recent-searches-container"] {
- background-color: rgba(25, 25, 25, 0.6);
- backdrop-filter: blur(10px);
-}
-
-[data-test="contextmenu"] {
- border: 1px solid var(--wave-color-opacity-contrast-fill-ultra-thin) !important;
-}
-
-[class^="_dataContainer_"]::before {
- background-image: var(--img);
- filter: blur(10px) brightness(0.4);
-}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7fe9d3e
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "luna/tsconfig.json"
+}