diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 7accab5..096cdb6 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,12 +1,12 @@
-# These are supported funding model platforms
-
-github: [night0721, ThunderE75] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
-patreon: # Replace with a single Patreon username
-open_collective: # Replace with a single Open Collective username
-ko_fi: cathteam
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+# These are supported funding model platforms
+
+github: [night0721, ThunderE75] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: cathteam
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml
index 6cdebaf..6a303a4 100644
--- a/.github/workflows/npm-publish.yml
+++ b/.github/workflows/npm-publish.yml
@@ -1,33 +1,33 @@
-# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
-# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
-
-name: Node.js Package
-
-on:
- release:
- types: [created]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 16
- - run: npm ci
- - run: npm test
-
- publish-npm:
- needs: build
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 16
- registry-url: https://registry.npmjs.org/
- - run: npm ci
- - run: npm publish
- env:
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
+# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
+# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
+
+name: Node.js Package
+
+on:
+ release:
+ types: [created]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+ - run: npm ci
+ - run: npm test
+
+ publish-npm:
+ needs: build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+ registry-url: https://registry.npmjs.org/
+ - run: npm ci
+ - run: npm publish
+ env:
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
diff --git a/.gitignore b/.gitignore
index 7140279..d701192 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-dist/
-node_modules/
-package-lock.json
-test.js
+dist/
+node_modules/
+package-lock.json
+test.js
docs/
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
index 44b808f..9cebef5 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,11 +1,11 @@
-src
-tsconfig.json
-node_modules
-package-lock.json
-.gitignore
-LICENSE
-.github
-docs
-test.js
-vercel.json
+src
+tsconfig.json
+node_modules
+package-lock.json
+.gitignore
+LICENSE
+.github
+docs
+test.js
+vercel.json
README.md
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index bcb050d..99d1d4a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,429 +1,429 @@
-Attribution-NonCommercial-ShareAlike 4.0 International
-
-=======================================================================
-
-Creative Commons Corporation ("Creative Commons") is not a law firm and
-does not provide legal services or legal advice. Distribution of
-Creative Commons public licenses does not create a lawyer-client or
-other relationship. Creative Commons makes its licenses and related
-information available on an "as-is" basis. Creative Commons gives no
-warranties regarding its licenses, any material licensed under their
-terms and conditions, or any related information. Creative Commons
-disclaims all liability for damages resulting from their use to the
-fullest extent possible.
-
-Using Creative Commons Public Licenses
-
-Creative Commons public licenses provide a standard set of terms and
-conditions that creators and other rights holders may use to share
-original works of authorship and other material subject to copyright
-and certain other rights specified in the public license below. The
-following considerations are for informational purposes only, are not
-exhaustive, and do not form part of our licenses.
-
- Considerations for licensors: Our public licenses are
- intended for use by those authorized to give the public
- permission to use material in ways otherwise restricted by
- copyright and certain other rights. Our licenses are
- irrevocable. Licensors should read and understand the terms
- and conditions of the license they choose before applying it.
- Licensors should also secure all rights necessary before
- applying our licenses so that the public can reuse the
- material as expected. Licensors should clearly mark any
- material not subject to the license. This includes other CC-
- licensed material, or material used under an exception or
- limitation to copyright. More considerations for licensors:
- wiki.creativecommons.org/Considerations_for_licensors
-
- Considerations for the public: By using one of our public
- licenses, a licensor grants the public permission to use the
- licensed material under specified terms and conditions. If
- the licensor's permission is not necessary for any reason--for
- example, because of any applicable exception or limitation to
- copyright--then that use is not regulated by the license. Our
- licenses grant only permissions under copyright and certain
- other rights that a licensor has authority to grant. Use of
- the licensed material may still be restricted for other
- reasons, including because others have copyright or other
- rights in the material. A licensor may make special requests,
- such as asking that all changes be marked or described.
- Although not required by our licenses, you are encouraged to
- respect those requests where reasonable. More_considerations
- for the public:
- wiki.creativecommons.org/Considerations_for_licensees
-
-=======================================================================
-
-Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
-Public License
-
-By exercising the Licensed Rights (defined below), You accept and agree
-to be bound by the terms and conditions of this Creative Commons
-Attribution-NonCommercial-ShareAlike 4.0 International Public License
-("Public License"). To the extent this Public License may be
-interpreted as a contract, You are granted the Licensed Rights in
-consideration of Your acceptance of these terms and conditions, and the
-Licensor grants You such rights in consideration of benefits the
-Licensor receives from making the Licensed Material available under
-these terms and conditions.
-
-Section 1 -- Definitions.
-
-a. Adapted Material means material subject to Copyright and Similar
-Rights that is derived from or based upon the Licensed Material
-and in which the Licensed Material is translated, altered,
-arranged, transformed, or otherwise modified in a manner requiring
-permission under the Copyright and Similar Rights held by the
-Licensor. For purposes of this Public License, where the Licensed
-Material is a musical work, performance, or sound recording,
-Adapted Material is always produced where the Licensed Material is
-synched in timed relation with a moving image.
-
-b. Adapter's License means the license You apply to Your Copyright
-and Similar Rights in Your contributions to Adapted Material in
-accordance with the terms and conditions of this Public License.
-
-c. BY-NC-SA Compatible License means a license listed at
-creativecommons.org/compatiblelicenses, approved by Creative
-Commons as essentially the equivalent of this Public License.
-
-d. Copyright and Similar Rights means copyright and/or similar rights
-closely related to copyright including, without limitation,
-performance, broadcast, sound recording, and Sui Generis Database
-Rights, without regard to how the rights are labeled or
-categorized. For purposes of this Public License, the rights
-specified in Section 2(b)(1)-(2) are not Copyright and Similar
-Rights.
-
-e. Effective Technological Measures means those measures that, in the
-absence of proper authority, may not be circumvented under laws
-fulfilling obligations under Article 11 of the WIPO Copyright
-Treaty adopted on December 20, 1996, and/or similar international
-agreements.
-
-f. Exceptions and Limitations means fair use, fair dealing, and/or
-any other exception or limitation to Copyright and Similar Rights
-that applies to Your use of the Licensed Material.
-
-g. License Elements means the license attributes listed in the name
-of a Creative Commons Public License. The License Elements of this
-Public License are Attribution, NonCommercial, and ShareAlike.
-
-h. Licensed Material means the artistic or literary work, database,
-or other material to which the Licensor applied this Public
-License.
-
-i. Licensed Rights means the rights granted to You subject to the
-terms and conditions of this Public License, which are limited to
-all Copyright and Similar Rights that apply to Your use of the
-Licensed Material and that the Licensor has authority to license.
-
-j. Licensor means the individual(s) or entity(ies) granting rights
-under this Public License.
-
-k. NonCommercial means not primarily intended for or directed towards
-commercial advantage or monetary compensation. For purposes of
-this Public License, the exchange of the Licensed Material for
-other material subject to Copyright and Similar Rights by digital
-file-sharing or similar means is NonCommercial provided there is
-no payment of monetary compensation in connection with the
-exchange.
-
-l. Share means to provide material to the public by any means or
-process that requires permission under the Licensed Rights, such
-as reproduction, public display, public performance, distribution,
-dissemination, communication, or importation, and to make material
-available to the public including in ways that members of the
-public may access the material from a place and at a time
-individually chosen by them.
-
-m. Sui Generis Database Rights means rights other than copyright
-resulting from Directive 96/9/EC of the European Parliament and of
-the Council of 11 March 1996 on the legal protection of databases,
-as amended and/or succeeded, as well as other essentially
-equivalent rights anywhere in the world.
-
-n. You means the individual or entity exercising the Licensed Rights
-under this Public License. Your has a corresponding meaning.
-
-Section 2 -- Scope.
-
-a. License grant.
-
- 1. Subject to the terms and conditions of this Public License,
- the Licensor hereby grants You a worldwide, royalty-free,
- non-sublicensable, non-exclusive, irrevocable license to
- exercise the Licensed Rights in the Licensed Material to:
-
- a. reproduce and Share the Licensed Material, in whole or
- in part, for NonCommercial purposes only; and
-
- b. produce, reproduce, and Share Adapted Material for
- NonCommercial purposes only.
-
- 2. Exceptions and Limitations. For the avoidance of doubt, where
- Exceptions and Limitations apply to Your use, this Public
- License does not apply, and You do not need to comply with
- its terms and conditions.
-
- 3. Term. The term of this Public License is specified in Section
- 6(a).
-
- 4. Media and formats; technical modifications allowed. The
- Licensor authorizes You to exercise the Licensed Rights in
- all media and formats whether now known or hereafter created,
- and to make technical modifications necessary to do so. The
- Licensor waives and/or agrees not to assert any right or
- authority to forbid You from making technical modifications
- necessary to exercise the Licensed Rights, including
- technical modifications necessary to circumvent Effective
- Technological Measures. For purposes of this Public License,
- simply making modifications authorized by this Section 2(a)
- (4) never produces Adapted Material.
-
- 5. Downstream recipients.
-
- a. Offer from the Licensor -- Licensed Material. Every
- recipient of the Licensed Material automatically
- receives an offer from the Licensor to exercise the
- Licensed Rights under the terms and conditions of this
- Public License.
-
- b. Additional offer from the Licensor -- Adapted Material.
- Every recipient of Adapted Material from You
- automatically receives an offer from the Licensor to
- exercise the Licensed Rights in the Adapted Material
- under the conditions of the Adapter's License You apply.
-
- c. No downstream restrictions. You may not offer or impose
- any additional or different terms or conditions on, or
- apply any Effective Technological Measures to, the
- Licensed Material if doing so restricts exercise of the
- Licensed Rights by any recipient of the Licensed
- Material.
-
- 6. No endorsement. Nothing in this Public License constitutes or
- may be construed as permission to assert or imply that You
- are, or that Your use of the Licensed Material is, connected
- with, or sponsored, endorsed, or granted official status by,
- the Licensor or others designated to receive attribution as
- provided in Section 3(a)(1)(A)(i).
-
-b. Other rights.
-
- 1. Moral rights, such as the right of integrity, are not
- licensed under this Public License, nor are publicity,
- privacy, and/or other similar personality rights; however, to
- the extent possible, the Licensor waives and/or agrees not to
- assert any such rights held by the Licensor to the limited
- extent necessary to allow You to exercise the Licensed
- Rights, but not otherwise.
-
- 2. Patent and trademark rights are not licensed under this
- Public License.
-
- 3. To the extent possible, the Licensor waives any right to
- collect royalties from You for the exercise of the Licensed
- Rights, whether directly or through a collecting society
- under any voluntary or waivable statutory or compulsory
- licensing scheme. In all other cases the Licensor expressly
- reserves any right to collect such royalties, including when
- the Licensed Material is used other than for NonCommercial
- purposes.
-
-Section 3 -- License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the
-following conditions.
-
-a. Attribution.
-
- 1. If You Share the Licensed Material (including in modified
- form), You must:
-
- a. retain the following if it is supplied by the Licensor
- with the Licensed Material:
-
- i. identification of the creator(s) of the Licensed
- Material and any others designated to receive
- attribution, in any reasonable manner requested by
- the Licensor (including by pseudonym if
- designated);
-
- ii. a copyright notice;
-
- iii. a notice that refers to this Public License;
-
- iv. a notice that refers to the disclaimer of
- warranties;
-
- v. a URI or hyperlink to the Licensed Material to the
- extent reasonably practicable;
-
- b. indicate if You modified the Licensed Material and
- retain an indication of any previous modifications; and
-
- c. indicate the Licensed Material is licensed under this
- Public License, and include the text of, or the URI or
- hyperlink to, this Public License.
-
- 2. You may satisfy the conditions in Section 3(a)(1) in any
- reasonable manner based on the medium, means, and context in
- which You Share the Licensed Material. For example, it may be
- reasonable to satisfy the conditions by providing a URI or
- hyperlink to a resource that includes the required
- information.
- 3. If requested by the Licensor, You must remove any of the
- information required by Section 3(a)(1)(A) to the extent
- reasonably practicable.
-
-b. ShareAlike.
-
- In addition to the conditions in Section 3(a), if You Share
- Adapted Material You produce, the following conditions also apply.
-
- 1. The Adapter's License You apply must be a Creative Commons
- license with the same License Elements, this version or
- later, or a BY-NC-SA Compatible License.
-
- 2. You must include the text of, or the URI or hyperlink to, the
- Adapter's License You apply. You may satisfy this condition
- in any reasonable manner based on the medium, means, and
- context in which You Share Adapted Material.
-
- 3. You may not offer or impose any additional or different terms
- or conditions on, or apply any Effective Technological
- Measures to, Adapted Material that restrict exercise of the
- rights granted under the Adapter's License You apply.
-
-Section 4 -- Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that
-apply to Your use of the Licensed Material:
-
-a. for the avoidance of doubt, Section 2(a)(1) grants You the right
-to extract, reuse, reproduce, and Share all or a substantial
-portion of the contents of the database for NonCommercial purposes
-only;
-
-b. if You include all or a substantial portion of the database
-contents in a database in which You have Sui Generis Database
-Rights, then the database in which You have Sui Generis Database
-Rights (but not its individual contents) is Adapted Material,
-including for purposes of Section 3(b); and
-
-c. You must comply with the conditions in Section 3(a) if You Share
-all or a substantial portion of the contents of the database.
-
-For the avoidance of doubt, this Section 4 supplements and does not
-replace Your obligations under this Public License where the Licensed
-Rights include other Copyright and Similar Rights.
-
-Section 5 -- Disclaimer of Warranties and Limitation of Liability.
-
-a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
-EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
-AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
-ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
-IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
-WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
-ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
-KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
-ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
-
-b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
-TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
-NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
-INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
-COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
-USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
-ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
-DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
-IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
-
-c. The disclaimer of warranties and limitation of liability provided
-above shall be interpreted in a manner that, to the extent
-possible, most closely approximates an absolute disclaimer and
-waiver of all liability.
-
-Section 6 -- Term and Termination.
-
-a. This Public License applies for the term of the Copyright and
-Similar Rights licensed here. However, if You fail to comply with
-this Public License, then Your rights under this Public License
-terminate automatically.
-
-b. Where Your right to use the Licensed Material has terminated under
-Section 6(a), it reinstates:
-
- 1. automatically as of the date the violation is cured, provided
- it is cured within 30 days of Your discovery of the
- violation; or
-
- 2. upon express reinstatement by the Licensor.
-
- For the avoidance of doubt, this Section 6(b) does not affect any
- right the Licensor may have to seek remedies for Your violations
- of this Public License.
-
-c. For the avoidance of doubt, the Licensor may also offer the
-Licensed Material under separate terms or conditions or stop
-distributing the Licensed Material at any time; however, doing so
-will not terminate this Public License.
-
-d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
-License.
-
-Section 7 -- Other Terms and Conditions.
-
-a. The Licensor shall not be bound by any additional or different
-terms or conditions communicated by You unless expressly agreed.
-
-b. Any arrangements, understandings, or agreements regarding the
-Licensed Material not stated herein are separate from and
-independent of the terms and conditions of this Public License.
-
-Section 8 -- Interpretation.
-
-a. For the avoidance of doubt, this Public License does not, and
-shall not be interpreted to, reduce, limit, restrict, or impose
-conditions on any use of the Licensed Material that could lawfully
-be made without permission under this Public License.
-
-b. To the extent possible, if any provision of this Public License is
-deemed unenforceable, it shall be automatically reformed to the
-minimum extent necessary to make it enforceable. If the provision
-cannot be reformed, it shall be severed from this Public License
-without affecting the enforceability of the remaining terms and
-conditions.
-
-c. No term or condition of this Public License will be waived and no
-failure to comply consented to unless expressly agreed to by the
-Licensor.
-
-d. Nothing in this Public License constitutes or may be interpreted
-as a limitation upon, or waiver of, any privileges and immunities
-that apply to the Licensor or You, including from the legal
-processes of any jurisdiction or authority.
-
-=======================================================================
-
-Creative Commons is not a party to its public
-licenses. Notwithstanding, Creative Commons may elect to apply one of
-its public licenses to material it publishes and in those instances
-will be considered the “Licensor.” The text of the Creative Commons
-public licenses is dedicated to the public domain under the CC0 Public
-Domain Dedication. Except for the limited purpose of indicating that
-material is shared under a Creative Commons public license or as
-otherwise permitted by the Creative Commons policies published at
-creativecommons.org/policies, Creative Commons does not authorize the
-use of the trademark "Creative Commons" or any other trademark or logo
-of Creative Commons without its prior written consent including,
-without limitation, in connection with any unauthorized modifications
-to any of its public licenses or any other arrangements,
-understandings, or agreements concerning use of licensed material. For
-the avoidance of doubt, this paragraph does not form part of the
-public licenses.
-
-Creative Commons may be contacted at creativecommons.org.
+Attribution-NonCommercial-ShareAlike 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+ Considerations for licensors: Our public licenses are
+ intended for use by those authorized to give the public
+ permission to use material in ways otherwise restricted by
+ copyright and certain other rights. Our licenses are
+ irrevocable. Licensors should read and understand the terms
+ and conditions of the license they choose before applying it.
+ Licensors should also secure all rights necessary before
+ applying our licenses so that the public can reuse the
+ material as expected. Licensors should clearly mark any
+ material not subject to the license. This includes other CC-
+ licensed material, or material used under an exception or
+ limitation to copyright. More considerations for licensors:
+ wiki.creativecommons.org/Considerations_for_licensors
+
+ Considerations for the public: By using one of our public
+ licenses, a licensor grants the public permission to use the
+ licensed material under specified terms and conditions. If
+ the licensor's permission is not necessary for any reason--for
+ example, because of any applicable exception or limitation to
+ copyright--then that use is not regulated by the license. Our
+ licenses grant only permissions under copyright and certain
+ other rights that a licensor has authority to grant. Use of
+ the licensed material may still be restricted for other
+ reasons, including because others have copyright or other
+ rights in the material. A licensor may make special requests,
+ such as asking that all changes be marked or described.
+ Although not required by our licenses, you are encouraged to
+ respect those requests where reasonable. More_considerations
+ for the public:
+ wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
+Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution-NonCommercial-ShareAlike 4.0 International Public License
+("Public License"). To the extent this Public License may be
+interpreted as a contract, You are granted the Licensed Rights in
+consideration of Your acceptance of these terms and conditions, and the
+Licensor grants You such rights in consideration of benefits the
+Licensor receives from making the Licensed Material available under
+these terms and conditions.
+
+Section 1 -- Definitions.
+
+a. Adapted Material means material subject to Copyright and Similar
+Rights that is derived from or based upon the Licensed Material
+and in which the Licensed Material is translated, altered,
+arranged, transformed, or otherwise modified in a manner requiring
+permission under the Copyright and Similar Rights held by the
+Licensor. For purposes of this Public License, where the Licensed
+Material is a musical work, performance, or sound recording,
+Adapted Material is always produced where the Licensed Material is
+synched in timed relation with a moving image.
+
+b. Adapter's License means the license You apply to Your Copyright
+and Similar Rights in Your contributions to Adapted Material in
+accordance with the terms and conditions of this Public License.
+
+c. BY-NC-SA Compatible License means a license listed at
+creativecommons.org/compatiblelicenses, approved by Creative
+Commons as essentially the equivalent of this Public License.
+
+d. Copyright and Similar Rights means copyright and/or similar rights
+closely related to copyright including, without limitation,
+performance, broadcast, sound recording, and Sui Generis Database
+Rights, without regard to how the rights are labeled or
+categorized. For purposes of this Public License, the rights
+specified in Section 2(b)(1)-(2) are not Copyright and Similar
+Rights.
+
+e. Effective Technological Measures means those measures that, in the
+absence of proper authority, may not be circumvented under laws
+fulfilling obligations under Article 11 of the WIPO Copyright
+Treaty adopted on December 20, 1996, and/or similar international
+agreements.
+
+f. Exceptions and Limitations means fair use, fair dealing, and/or
+any other exception or limitation to Copyright and Similar Rights
+that applies to Your use of the Licensed Material.
+
+g. License Elements means the license attributes listed in the name
+of a Creative Commons Public License. The License Elements of this
+Public License are Attribution, NonCommercial, and ShareAlike.
+
+h. Licensed Material means the artistic or literary work, database,
+or other material to which the Licensor applied this Public
+License.
+
+i. Licensed Rights means the rights granted to You subject to the
+terms and conditions of this Public License, which are limited to
+all Copyright and Similar Rights that apply to Your use of the
+Licensed Material and that the Licensor has authority to license.
+
+j. Licensor means the individual(s) or entity(ies) granting rights
+under this Public License.
+
+k. NonCommercial means not primarily intended for or directed towards
+commercial advantage or monetary compensation. For purposes of
+this Public License, the exchange of the Licensed Material for
+other material subject to Copyright and Similar Rights by digital
+file-sharing or similar means is NonCommercial provided there is
+no payment of monetary compensation in connection with the
+exchange.
+
+l. Share means to provide material to the public by any means or
+process that requires permission under the Licensed Rights, such
+as reproduction, public display, public performance, distribution,
+dissemination, communication, or importation, and to make material
+available to the public including in ways that members of the
+public may access the material from a place and at a time
+individually chosen by them.
+
+m. Sui Generis Database Rights means rights other than copyright
+resulting from Directive 96/9/EC of the European Parliament and of
+the Council of 11 March 1996 on the legal protection of databases,
+as amended and/or succeeded, as well as other essentially
+equivalent rights anywhere in the world.
+
+n. You means the individual or entity exercising the Licensed Rights
+under this Public License. Your has a corresponding meaning.
+
+Section 2 -- Scope.
+
+a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part, for NonCommercial purposes only; and
+
+ b. produce, reproduce, and Share Adapted Material for
+ NonCommercial purposes only.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. Additional offer from the Licensor -- Adapted Material.
+ Every recipient of Adapted Material from You
+ automatically receives an offer from the Licensor to
+ exercise the Licensed Rights in the Adapted Material
+ under the conditions of the Adapter's License You apply.
+
+ c. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties, including when
+ the Licensed Material is used other than for NonCommercial
+ purposes.
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+b. ShareAlike.
+
+ In addition to the conditions in Section 3(a), if You Share
+ Adapted Material You produce, the following conditions also apply.
+
+ 1. The Adapter's License You apply must be a Creative Commons
+ license with the same License Elements, this version or
+ later, or a BY-NC-SA Compatible License.
+
+ 2. You must include the text of, or the URI or hyperlink to, the
+ Adapter's License You apply. You may satisfy this condition
+ in any reasonable manner based on the medium, means, and
+ context in which You Share Adapted Material.
+
+ 3. You may not offer or impose any additional or different terms
+ or conditions on, or apply any Effective Technological
+ Measures to, Adapted Material that restrict exercise of the
+ rights granted under the Adapter's License You apply.
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+to extract, reuse, reproduce, and Share all or a substantial
+portion of the contents of the database for NonCommercial purposes
+only;
+
+b. if You include all or a substantial portion of the database
+contents in a database in which You have Sui Generis Database
+Rights, then the database in which You have Sui Generis Database
+Rights (but not its individual contents) is Adapted Material,
+including for purposes of Section 3(b); and
+
+c. You must comply with the conditions in Section 3(a) if You Share
+all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+c. The disclaimer of warranties and limitation of liability provided
+above shall be interpreted in a manner that, to the extent
+possible, most closely approximates an absolute disclaimer and
+waiver of all liability.
+
+Section 6 -- Term and Termination.
+
+a. This Public License applies for the term of the Copyright and
+Similar Rights licensed here. However, if You fail to comply with
+this Public License, then Your rights under this Public License
+terminate automatically.
+
+b. Where Your right to use the Licensed Material has terminated under
+Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+c. For the avoidance of doubt, the Licensor may also offer the
+Licensed Material under separate terms or conditions or stop
+distributing the Licensed Material at any time; however, doing so
+will not terminate this Public License.
+
+d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+License.
+
+Section 7 -- Other Terms and Conditions.
+
+a. The Licensor shall not be bound by any additional or different
+terms or conditions communicated by You unless expressly agreed.
+
+b. Any arrangements, understandings, or agreements regarding the
+Licensed Material not stated herein are separate from and
+independent of the terms and conditions of this Public License.
+
+Section 8 -- Interpretation.
+
+a. For the avoidance of doubt, this Public License does not, and
+shall not be interpreted to, reduce, limit, restrict, or impose
+conditions on any use of the Licensed Material that could lawfully
+be made without permission under this Public License.
+
+b. To the extent possible, if any provision of this Public License is
+deemed unenforceable, it shall be automatically reformed to the
+minimum extent necessary to make it enforceable. If the provision
+cannot be reformed, it shall be severed from this Public License
+without affecting the enforceability of the remaining terms and
+conditions.
+
+c. No term or condition of this Public License will be waived and no
+failure to comply consented to unless expressly agreed to by the
+Licensor.
+
+d. Nothing in this Public License constitutes or may be interpreted
+as a limitation upon, or waiver of, any privileges and immunities
+that apply to the Licensor or You, including from the legal
+processes of any jurisdiction or authority.
+
+=======================================================================
+
+Creative Commons is not a party to its public
+licenses. Notwithstanding, Creative Commons may elect to apply one of
+its public licenses to material it publishes and in those instances
+will be considered the “Licensor.” The text of the Creative Commons
+public licenses is dedicated to the public domain under the CC0 Public
+Domain Dedication. Except for the limited purpose of indicating that
+material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the
+public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/README.md b/README.md
index 6abe550..172ed59 100644
--- a/README.md
+++ b/README.md
@@ -1,61 +1,61 @@
-
CATH
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-**Cath** is a powerful [Node.js](https://nodejs.org) module that can easily interact and get data from the Cath API
-If you like this package, feel free to **Star** and **fork** this repository.
-
-# Install the package ✔
-
-Download from npm
-
-```powershell
-npm install cath
-```
-
-Download from yarn
-
-```powershell
-yarn add cath
-```
-
-## Examples
-
-### Launch of the module
-
-```js
-const cath = require("cath");
-
-const reddit_data = await cath.getreddit("meme");
-console.log(reddit_data); // returns an object
-
-const answer = await cath.random8ball();
-console.log(answer); // a random answer from 8ball
-```
-
-# Support, Feature Request & Bug Reports
-
-## Support & Feature Request
-
-Join the official [Support Server](https://discord.gg/SbQHChmGcp) on Discord & we will be happy to assist you.
-To Request new features contact us on Discord using the support server.
-
-## Report Bugs
-
-You can report bugs or issues by opening a issue in this repository. Alternatevely you can also contact us on Discord using the support server.
-
-
-
-
+ CATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+**Cath** is a powerful [Node.js](https://nodejs.org) module that can easily interact and get data from the Cath API
+If you like this package, feel free to **Star** and **fork** this repository.
+
+# Install the package ✔
+
+Download from npm
+
+```powershell
+npm install cath
+```
+
+Download from yarn
+
+```powershell
+yarn add cath
+```
+
+## Examples
+
+### Launch of the module
+
+```js
+const cath = require("cath");
+
+const reddit_data = await cath.getreddit("meme");
+console.log(reddit_data); // returns an object
+
+const answer = await cath.random8ball();
+console.log(answer); // a random answer from 8ball
+```
+
+# Support, Feature Request & Bug Reports
+
+## Support & Feature Request
+
+Join the official [Support Server](https://discord.gg/SbQHChmGcp) on Discord & we will be happy to assist you.
+To Request new features contact us on Discord using the support server.
+
+## Report Bugs
+
+You can report bugs or issues by opening a issue in this repository. Alternatevely you can also contact us on Discord using the support server.
+
+
+
+
diff --git a/src/CODMClient/codmclient.interface.ts b/src/CODMClient/codmclient.interface.ts
index 2e85613..212198f 100644
--- a/src/CODMClient/codmclient.interface.ts
+++ b/src/CODMClient/codmclient.interface.ts
@@ -1,22 +1,22 @@
-export interface CODMClientOptions {
- /**
- * Authorisation key for the API
- */
- key: string;
-}
-export interface PerkData {
- name: string;
- perk: string;
- effects: string;
- type: string;
-}
-export interface ScorestreakData {
- name: string;
- description: string;
- special: string;
- cost: number;
- type: string;
- manual: boolean;
- preview: string;
- preview_video: string;
-}
+export interface CODMClientOptions {
+ /**
+ * Authorisation key for the API
+ */
+ key: string;
+}
+export interface PerkData {
+ name: string;
+ perk: string;
+ effects: string;
+ type: string;
+}
+export interface ScorestreakData {
+ name: string;
+ description: string;
+ special: string;
+ cost: number;
+ type: string;
+ manual: boolean;
+ preview: string;
+ preview_video: string;
+}
diff --git a/src/CODMClient/codmclient.ts b/src/CODMClient/codmclient.ts
index 6514c6b..f82ffbd 100644
--- a/src/CODMClient/codmclient.ts
+++ b/src/CODMClient/codmclient.ts
@@ -1,47 +1,47 @@
-import axios from "axios";
-import { CathError } from "../Error/CathError";
-import { config } from "../";
-import { PerkData, ScorestreakData } from "./codmclient.interface";
-/**
- * @name APIClient
- * @kind constructor
- * @param {String} key Authorization Key for API (Only for CODM commands)
- */
-export class CODMClient {
- constructor(public key: string) {
- if (!key) throw new CathError("Missing 'key' property");
- if (key && typeof key !== "string")
- throw new CathError("API key must be a string");
- }
- /**
- * Sends a CODM perk object
- * @return {Promise}
- * @param {String} name
- */
- public async getperk(name: string): Promise {
- const data = await axios
- .get(`${config.api}/api/v1/codm/perk?name=${name}`, {
- headers: {
- Authorization: this.key,
- },
- })
- .then(res => res.data)
- .catch(err => {
- throw new CathError(`Unauthorized to use`);
- });
- return data;
- }
- public async getscorestreak(name: string): Promise {
- const data = await axios
- .get(`${config.api}/api/v1/codm/scorestreak?name=${name}`, {
- headers: {
- Authorization: this.key,
- },
- })
- .then(res => res.data)
- .catch(err => {
- throw new CathError(`Unauthorized to use`);
- });
- return data;
- }
-}
+import axios from "axios";
+import { CathError } from "../Error/CathError";
+import { config } from "../";
+import { PerkData, ScorestreakData } from "./codmclient.interface";
+/**
+ * @name APIClient
+ * @kind constructor
+ * @param {String} key Authorization Key for API (Only for CODM commands)
+ */
+export class CODMClient {
+ constructor(public key: string) {
+ if (!key) throw new CathError("Missing 'key' property");
+ if (key && typeof key !== "string")
+ throw new CathError("API key must be a string");
+ }
+ /**
+ * Sends a CODM perk object
+ * @return {Promise}
+ * @param {String} name
+ */
+ public async getperk(name: string): Promise {
+ const data = await axios
+ .get(`${config.api}/api/v1/codm/perk?name=${name}`, {
+ headers: {
+ Authorization: this.key,
+ },
+ })
+ .then(res => res.data)
+ .catch(err => {
+ throw new CathError(`Unauthorized to use`);
+ });
+ return data;
+ }
+ public async getscorestreak(name: string): Promise {
+ const data = await axios
+ .get(`${config.api}/api/v1/codm/scorestreak?name=${name}`, {
+ headers: {
+ Authorization: this.key,
+ },
+ })
+ .then(res => res.data)
+ .catch(err => {
+ throw new CathError(`Unauthorized to use`);
+ });
+ return data;
+ }
+}
diff --git a/src/CODMClient/index.ts b/src/CODMClient/index.ts
index 96e53ac..5733f11 100644
--- a/src/CODMClient/index.ts
+++ b/src/CODMClient/index.ts
@@ -1,6 +1,6 @@
-export {
- CODMClientOptions,
- PerkData,
- ScorestreakData,
-} from "./codmclient.interface";
-export { CODMClient } from "./codmclient";
+export {
+ CODMClientOptions,
+ PerkData,
+ ScorestreakData,
+} from "./codmclient.interface";
+export { CODMClient } from "./codmclient";
diff --git a/src/CodeClient/codeclient.interface.ts b/src/CodeClient/codeclient.interface.ts
index 2e94d4b..b1a6884 100644
--- a/src/CodeClient/codeclient.interface.ts
+++ b/src/CodeClient/codeclient.interface.ts
@@ -1,3 +1,3 @@
-export interface CodeData {
- id: string;
-}
+export interface CodeData {
+ id: string;
+}
diff --git a/src/CodeClient/codeclient.ts b/src/CodeClient/codeclient.ts
index fe78892..06f8797 100644
--- a/src/CodeClient/codeclient.ts
+++ b/src/CodeClient/codeclient.ts
@@ -1,32 +1,32 @@
-import axios from "axios";
-import { config } from "../";
-import { CodeData } from "./codeclient.interface";
-import { CathError } from "../Error/CathError";
-/**
- * @name CodeClient
- * @kind constructor
- */
-export class CodeClient {
- constructor() {}
- /**
- * Sends the link of the code
- * @return {Promise}
- * @param {String} key
- * @param {String} code
- */
- public async createBin(key: String, code: String): Promise {
- if (!key) throw new CathError("Missing 'key' property");
- if (!code) throw new CathError("Missing 'code' property");
- const data = await axios
- .post(config.code, {
- key,
- value: code,
- })
- .then(res => res.data);
- if (data?.url) {
- return data?.url;
- } else {
- throw new CathError(`Code already exist`);
- }
- }
-}
+import axios from "axios";
+import { config } from "../";
+import { CodeData } from "./codeclient.interface";
+import { CathError } from "../Error/CathError";
+/**
+ * @name CodeClient
+ * @kind constructor
+ */
+export class CodeClient {
+ constructor() {}
+ /**
+ * Sends the link of the code
+ * @return {Promise}
+ * @param {String} key
+ * @param {String} code
+ */
+ public async createBin(key: String, code: String): Promise {
+ if (!key) throw new CathError("Missing 'key' property");
+ if (!code) throw new CathError("Missing 'code' property");
+ const data = await axios
+ .post(config.code, {
+ key,
+ value: code,
+ })
+ .then(res => res.data);
+ if (data?.url) {
+ return data?.url;
+ } else {
+ throw new CathError(`Code already exist`);
+ }
+ }
+}
diff --git a/src/CodeClient/index.ts b/src/CodeClient/index.ts
index b941bd7..3fee22d 100644
--- a/src/CodeClient/index.ts
+++ b/src/CodeClient/index.ts
@@ -1,2 +1,2 @@
-export { CodeData } from "./codeclient.interface";
-export { CodeClient } from "./codeclient";
+export { CodeData } from "./codeclient.interface";
+export { CodeClient } from "./codeclient";
diff --git a/src/Error/CathError.ts b/src/Error/CathError.ts
index 15ab268..47c435f 100644
--- a/src/Error/CathError.ts
+++ b/src/Error/CathError.ts
@@ -1,6 +1,6 @@
-export class CathError extends Error {
- constructor(err: string) {
- super(err);
- console.log(`Cath Error: ${err}`);
- }
-}
+export class CathError extends Error {
+ constructor(err: string) {
+ super(err);
+ console.log(`Cath Error: ${err}`);
+ }
+}
diff --git a/src/GiveawaysClient/giveaway.interface.ts b/src/GiveawaysClient/giveaway.interface.ts
index 5eea30d..8883a5c 100644
--- a/src/GiveawaysClient/giveaway.interface.ts
+++ b/src/GiveawaysClient/giveaway.interface.ts
@@ -1,60 +1,60 @@
-import { Client } from "discord.js";
-export interface GiveawaySchema {
- Guild: string;
- Channel: string;
- Message: string;
- HostBy: string;
- End: number;
- Start: number;
- Award: string;
- Winners: number;
- Ended: boolean;
- Invites: number;
- Requirements: { Enabled: boolean; Roles?: [string] };
- Clickers: [string];
-}
-export interface InviteSchema {
- User: string;
- Invites: [
- object: {
- Guild: string;
- Invite: string;
- Invited: string;
- Inviter: string;
- Uses: number;
- }
- ];
-}
-export interface GiveawaysClientOptions {
- /**
- * Discord Client
- */
- client: Client;
- /**
- * Connection URI for the MongoDB
- */
- MongooseConnectionURI: string;
- /**
- * Customizable messages for the giveaway embed
- */
- GiveawayMessages: DefaultGiveawayMessages;
-}
-export interface DefaultGiveawayMessages {
- dmWinner: true;
- giveaway: "🎉🎉 **GIVEAWAY!** 🎉🎉";
- giveawayDescription: "🎁 Award: **{award}**\n🎊 Hosted by: {hostedBy}\n⏲️ Winner(s): `{winners}` \n🙏 Entrants: {totalParticipants} \n\n**Requirements:** {requirements}\n**Required Invites:** {invites}";
- giveawayFooterImage: "https://emoji.gg/assets/emoji/3461-giveaway.gif";
- winMessage: "congratulations {winners}! You have won **{prize}** from total `{totalParticipants}` entrants!";
- rerolledMessage: "Rerolled! {winner} is the new winner of the giveaway!"; // only {winner} placeholder
- toParticipate: "**Click the `Enter` button to enter the giveaway!**";
- newParticipant: "You have successfully entered for this giveaway! There are total `{totalParticipants}` entrants"; // no placeholders | ephemeral
- alreadyParticipated: "**You have already participated in this giveaway!**"; // no placeholders | ephemeral
- noParticipants: "There isn't enough entrant in this giveaway!"; // no placeholders
- dmMessage: "You have won a giveaway in **{guildName}**!\nPrize: [{prize}]({giveawayURL})";
- noWinner: "There isn't any winner in this giveaway due to not enough entrants"; // no {winner} placerholder
- alreadyEnded: "The giveaway had already ended!"; // no {winner} placeholder
- noWeeklyExp: "you dont have the required minimum weekly xp to join this giveaway";
- noLevel: "You dont have the minimum required level to join this giveaway";
- nonoRole: "You don't the required role(s)\n{requiredRoles} role(s) to join the giveaway";
- editParticipants: true;
-}
+import { Client } from "discord.js";
+export interface GiveawaySchema {
+ Guild: string;
+ Channel: string;
+ Message: string;
+ HostBy: string;
+ End: number;
+ Start: number;
+ Award: string;
+ Winners: number;
+ Ended: boolean;
+ Invites: number;
+ Requirements: { Enabled: boolean; Roles?: [string] };
+ Clickers: [string];
+}
+export interface InviteSchema {
+ User: string;
+ Invites: [
+ object: {
+ Guild: string;
+ Invite: string;
+ Invited: string;
+ Inviter: string;
+ Uses: number;
+ }
+ ];
+}
+export interface GiveawaysClientOptions {
+ /**
+ * Discord Client
+ */
+ client: Client;
+ /**
+ * Connection URI for the MongoDB
+ */
+ MongooseConnectionURI: string;
+ /**
+ * Customizable messages for the giveaway embed
+ */
+ GiveawayMessages: DefaultGiveawayMessages;
+}
+export interface DefaultGiveawayMessages {
+ dmWinner: true;
+ giveaway: "🎉🎉 **GIVEAWAY!** 🎉🎉";
+ giveawayDescription: "🎁 Award: **{award}**\n🎊 Hosted by: {hostedBy}\n⏲️ Winner(s): `{winners}` \n🙏 Entrants: {totalParticipants} \n\n**Requirements:** {requirements}\n**Required Invites:** {invites}";
+ giveawayFooterImage: "https://emoji.gg/assets/emoji/3461-giveaway.gif";
+ winMessage: "congratulations {winners}! You have won **{prize}** from total `{totalParticipants}` entrants!";
+ rerolledMessage: "Rerolled! {winner} is the new winner of the giveaway!"; // only {winner} placeholder
+ toParticipate: "**Click the `Enter` button to enter the giveaway!**";
+ newParticipant: "You have successfully entered for this giveaway! There are total `{totalParticipants}` entrants"; // no placeholders | ephemeral
+ alreadyParticipated: "**You have already participated in this giveaway!**"; // no placeholders | ephemeral
+ noParticipants: "There isn't enough entrant in this giveaway!"; // no placeholders
+ dmMessage: "You have won a giveaway in **{guildName}**!\nPrize: [{prize}]({giveawayURL})";
+ noWinner: "There isn't any winner in this giveaway due to not enough entrants"; // no {winner} placerholder
+ alreadyEnded: "The giveaway had already ended!"; // no {winner} placeholder
+ noWeeklyExp: "you dont have the required minimum weekly xp to join this giveaway";
+ noLevel: "You dont have the minimum required level to join this giveaway";
+ nonoRole: "You don't the required role(s)\n{requiredRoles} role(s) to join the giveaway";
+ editParticipants: true;
+}
diff --git a/src/GiveawaysClient/giveaway.ts b/src/GiveawaysClient/giveaway.ts
index f568e41..26a90eb 100644
--- a/src/GiveawaysClient/giveaway.ts
+++ b/src/GiveawaysClient/giveaway.ts
@@ -1,756 +1,756 @@
-import mongoose, { Schema, model } from "mongoose";
-import {
- Client,
- Snowflake,
- Message,
- MessageActionRow,
- MessageButton,
- MessageEmbed,
- TextChannel,
- GuildMember,
- ButtonInteraction,
-} from "discord.js";
-import { CathError } from "../Error/CathError";
-import {
- GiveawaySchema,
- GiveawaysClientOptions,
- DefaultGiveawayMessages,
- InviteSchema,
-} from "./giveaway.interface";
-import { parseString } from "../functions/ms";
-export class GiveawaysClient {
- public inviteschema = model(
- "cath-invite",
- new Schema({
- User: { type: String, required: true },
- Invites: { type: Object, required: true },
- })
- );
- public schema = model(
- "cath-giveaways",
- new Schema({
- Guild: {
- type: String,
- required: true,
- },
- Channel: {
- type: String,
- required: true,
- },
- Message: {
- type: String,
- required: true,
- },
- HostBy: {
- type: String,
- required: true,
- },
- End: {
- type: Number,
- required: true,
- },
- Start: {
- type: Number,
- required: true,
- },
- Award: {
- type: String,
- required: true,
- },
- Winners: {
- type: Number,
- required: true,
- },
- Ended: {
- type: Boolean,
- default: false,
- },
- Invites: {
- type: Number,
- required: true,
- default: 0,
- },
- Requirements: {
- type: Object,
- default: { Enabled: Boolean, Roles: [] },
- },
- Clickers: {
- type: Array,
- default: [],
- },
- })
- );
- public client: Client;
- public GiveawayMessages: DefaultGiveawayMessages;
- public MongooseConnectionURI: string;
- /**
- * @name GiveawaysClient
- * @kind constructor
- * @param {GiveawaysClientOptions}options
- */
-
- constructor(options: GiveawaysClientOptions) {
- this.GiveawayMessages = options.GiveawayMessages || this.GiveawayMessages;
- this.client = options.client;
- this.MongooseConnectionURI = options.MongooseConnectionURI;
- mongoose
- .connect(this.MongooseConnectionURI, {
- useNewUrlParser: true,
- useUnifiedTopology: true,
- })
- .then(() => console.log("Connected to Giveaway Database"))
- .catch(e => {
- throw new CathError(e);
- });
- this.client.on("interactionCreate", async interaction => {
- if (interaction.isButton()) {
- let win = "" || [];
- let L = 0;
- let no = false;
- if (!interaction.guild) return;
- await (interaction.member as GuildMember).fetch();
- const id = interaction.customId;
- if (id.startsWith("g")) {
- const tag = id.split("_");
- if (tag[0] === "genter") {
- const data = await this.schema.findOne({
- Message: interaction.message.id,
- });
- if (data.Invites > 0) {
- const invitedata = await this.inviteschema.findOne({
- User: (interaction.member as GuildMember).id,
- });
- if (!invitedata) {
- await interaction.reply({
- content: "You have no invites, you can't enter",
- ephemeral: true,
- });
- } else {
- L = invitedata.Invites.map(o => o.Uses).reduce((acc, cur) => {
- return acc + cur;
- });
- if (data.Invites >= L) {
- await interaction.reply({
- content: "You have not enough invites, you can't enter",
- ephemeral: true,
- });
- no = true;
- }
- }
- }
- if (data.Requirements.Enabled) {
- if (data.Requirements.Roles.length) {
- const roles = data.Requirements.Roles.map(x =>
- (interaction.message as Message).guild.members.cache
- .get(interaction.user.id)
- .roles.cache.get(x)
- );
- if (!roles[0]) {
- const requiredRoles = (
- interaction.message as Message
- ).guild.roles.cache
- .filter(x => data.Requirements.Roles.includes(x.id))
- .filter(
- x =>
- !(interaction.message as Message).guild.members.cache
- .get(interaction.user.id)
- .roles.cache.get(x.id)
- )
- .map(x => `\`${x.name}\``)
- .join(", ");
- try {
- await interaction.reply({
- content: this.GiveawayMessages.nonoRole.replace(
- /{requiredRoles}/g,
- requiredRoles
- ),
- });
- } catch (e) {
- await interaction.followUp({
- content: this.GiveawayMessages.nonoRole.replace(
- /{requiredRoles}/g,
- requiredRoles
- ),
- });
- }
- }
- }
- }
- if (!data.Clickers.includes(interaction.user.id) && !no) {
- data.Clickers.push(interaction.user.id);
- data.save();
- try {
- await interaction.reply({
- content: this.GiveawayMessages.newParticipant.replace(
- /{totalParticipants}/g,
- data.Clickers.length.toString()
- ),
- });
- } catch (e) {
- await interaction.followUp({
- content: this.GiveawayMessages.newParticipant.replace(
- /{totalParticipants}/g,
- data.Clickers.length.toString()
- ),
- });
- }
- } else if (data.Clickers.includes(interaction.user.id) && !no) {
- await interaction.followUp({
- content: this.GiveawayMessages.alreadyParticipated,
- });
- } else if (!data.Clickers.includes(interaction.user.id) && no) {
- } else if (data.Clickers.includes(interaction.user.id) && no) {
- }
- }
- if (tag[0] === "greroll") {
- if (interaction.user.id !== tag[1])
- await interaction.reply({
- content: "Only the host can reroll the giveaway",
- });
- try {
- win = await this.reroll(
- this.client,
- interaction.message.id,
- interaction.message as Message
- );
- } catch (err) {
- console.log(err);
- await interaction.reply({
- content: "⚠️ **Unable To Find That Giveaway**",
- });
- }
- if (!win.length)
- interaction.channel.send(this.GiveawayMessages.noParticipants);
- else {
- await interaction.reply({
- content: "Rerolled",
- ephemeral: true,
- });
- interaction.channel.send({
- content: this.GiveawayMessages.rerolledMessage.replace(
- /{winner}/g,
- `<@${win}>`
- ),
- components: [
- new MessageActionRow().addComponents([
- new MessageButton()
- .setLabel("Giveaway")
- .setURL(
- `https://discord.com/channels/${interaction.guild.id}/${interaction.channel.id}/${interaction.message.id}`
- )
- .setStyle("LINK"),
- ]),
- ],
- });
- }
- }
- if (tag[0] === "gend") {
- if (interaction.user.id !== tag[1])
- await interaction.reply({
- content: "You Cannot End This Giveaway, Only The Host Can",
- });
- await interaction.reply({ content: "Ended", ephemeral: true });
- await this.endByButton(
- this.client,
- interaction.message.id,
- interaction
- );
- }
- }
- }
- });
- }
-
- private getButtons(host: string) {
- const reroll = new MessageButton()
- .setLabel("Reroll")
- .setStyle("SECONDARY")
- .setCustomId(`greroll_${host}`)
- .setDisabled(true);
-
- const end = new MessageButton()
- .setLabel("End")
- .setStyle("DANGER")
- .setCustomId(`gend_${host}`);
-
- const enter = new MessageButton()
- .setLabel("Enter")
- .setStyle("SUCCESS")
- .setCustomId(`genter_${host}`);
-
- const b = [enter, end, reroll];
- return b;
- }
-
- private async choose(winners: number, msgid: Snowflake, message: Message) {
- const data = await this.getByMessage(msgid);
- const final = [];
- if (data.Requirements.Enabled && data.Invites == 0) {
- const c = data.Clickers.filter(x =>
- this.checkRoles(x, data.Requirements.Roles, message)
- );
- for (let i = 0; i < winners; i++) {
- if (!c.length) return final[0] ? final : [];
- const win = c[Math.floor(Math.random() * c.length)];
- if (final.includes(win)) break;
- if (!win) return final[0] ? final : [];
- final.push(win);
- }
- } else {
- for (let i = 0; i < winners; i++) {
- if (!data.Clickers.length) return final[0] ? final : [];
- const win =
- data.Clickers[Math.floor(Math.random() * data.Clickers.length)];
- if (final.includes(win)) break;
- if (!win) return final[0] ? final : [];
- final.push(win);
- }
- }
- return final[0] ? final : [];
- }
-
- private checkRoles(
- userID: Snowflake,
- roleIDs: Snowflake[],
- message: Message
- ): Boolean {
- let res = null;
- roleIDs.forEach(roleID => {
- const role = message.guild.roles.cache.get(roleID);
- if (!message.guild.members.cache.get(userID).roles.cache.get(role.id))
- res = false;
- });
- if (res == false) return false;
- else return true;
- }
-
- private async editButtons(client: Client, data: GiveawaySchema) {
- const m = await (
- client.guilds.cache
- .get(data.Guild)
- .channels.cache.get(data.Channel) as TextChannel
- ).messages.fetch(data.Message);
- const bs = await this.getButtons(data.HostBy);
- bs.find(x => x.label == "Enter")
- .setDisabled()
- .setStyle("SECONDARY");
- bs.find(x => x.label == "End")
- .setDisabled()
- .setStyle("SECONDARY");
- bs.find(x => x.label == "Reroll")
- .setDisabled(false)
- .setStyle("SUCCESS");
- const row = new MessageActionRow().addComponents(bs);
- m.edit({
- components: [row],
- embeds: m.embeds,
- }).catch(e => {
- throw new CathError(e);
- });
- }
-
- private async giveawayEmbed(
- client: Client,
- status: string,
- { host, prize, endAfter, invites, winners, requirements }
- ) {
- const hostedBy =
- client.users.cache.get(host) ||
- (await client.users.fetch(host).catch(() => null));
- let req = "";
- if (requirements.Roles)
- req += `\n Role(s): ${requirements.Roles.map(x => `<@&${x}>`).join(
- ", "
- )}`;
- if (requirements.weeklyamari)
- req += `\n Weekly Amari: \`${requirements.weeklyamari}\``;
- if (requirements.amarilevel)
- req += `\n Amari Level: \`${requirements.amarilevel}\``;
- const embed = new MessageEmbed()
- .setTitle(`Status: ${status}! 🎉`)
- .setDescription(
- `${
- this.GiveawayMessages.toParticipate
- }\n${this.GiveawayMessages.giveawayDescription
- .replace(/{invites}/g, invites ? invites : "0")
- .replace(/{requirements}/g, req)
- .replace(/{hostedBy}/g, hostedBy || "Can't find the user")
- .replace(/{award}/g, prize)
- .replace(/{winners}/g, winners)
- .replace(/{totalParticipants}/g, "0")}`
- )
- .setColor("RANDOM")
- .setFooter({
- text: "Ends",
- iconURL: this.GiveawayMessages.giveawayFooterImage,
- })
- .setTimestamp(Date.now() + parseString(endAfter));
- return embed;
- }
-
- public async create(
- client: Client,
- { prize, host, winners, endAfter, invites, requirements, Channel }
- ) {
- if (!client)
- throw new CathError("client wasnt provided while creating giveaway!");
- if (!prize)
- throw new CathError("prize wasnt provided while creating giveaway!");
- if (typeof prize !== "string")
- throw new TypeError("prize should be a string");
- if (!host)
- throw new CathError("host wasnt provided while creating giveaway");
- if (!winners)
- throw new CathError(
- "winner count wasnt provided while creating giveaway"
- );
- if (isNaN(winners)) throw new TypeError("winners should be a Number");
- if (!endAfter)
- throw new CathError("time wasnt provided while creating giveaway");
- if (typeof endAfter !== "string")
- throw new TypeError("endAfter should be a string");
- if (
- invites < 0 &&
- invites == null &&
- invites == undefined &&
- typeof invites !== "number"
- ) {
- throw new CathError("invites wasnt provided while creating giveaway");
- }
- if (!Channel)
- throw new CathError("channel ID wasnt provided while creating giveaway");
- const status = "In Progress";
- const msg = await (client.channels.cache.get(Channel) as TextChannel).send({
- content: this.GiveawayMessages.giveaway,
- components: [new MessageActionRow().addComponents(this.getButtons(host))],
- embeds: [
- await this.giveawayEmbed(client, status, {
- host,
- prize,
- endAfter,
- invites,
- winners,
- requirements,
- }),
- ],
- });
-
- const data = await new this.schema({
- Message: msg.id,
- Channel: Channel,
- Guild: msg.guild.id,
- HostBy: host,
- Winners: winners,
- Award: prize,
- Start: Date.now(),
- End: Date.now() + parseString(endAfter),
- Invites: invites,
- Requirements: requirements,
- }).save();
- await this.startTimer(msg, data);
- }
-
- private async startTimer(message: Message, data, instant = false) {
- if (!message) throw new CathError("Missing 'message'");
- if (!data) throw new CathError("Missing 'data'");
- const msg = await (
- message.guild.channels.cache.get(data.Channel) as TextChannel
- ).messages.fetch(data.Message);
- await msg.fetch();
- const time = instant ? 0 : data.End - Date.now();
- setTimeout(async () => {
- const winners = await this.choose(data.winners, data.Message, message);
- if (!winners) {
- msg.channel.send({
- content: this.replacePlaceholders(
- this.GiveawayMessages.noWinner,
- data,
- msg
- ),
- });
- data.Ended = true;
- data.save();
- const embed = msg.embeds[0];
- embed.description = this.replacePlaceholders(
- this.GiveawayMessages.giveawayDescription,
- data,
- msg
- );
- msg.edit({ embeds: [embed] });
- this.editButtons(message.client, data);
- return "NO_WINNERS";
- }
- message.channel.send({
- content: this.replacePlaceholders(
- this.GiveawayMessages.winMessage,
- await this.getByMessage(data.Message),
- msg,
- winners as []
- ),
- });
-
- if (this.GiveawayMessages.dmWinner) {
- const dmEmbed = new MessageEmbed()
- .setTitle("You Won!")
- .setDescription(
- this.replacePlaceholders(
- this.GiveawayMessages.dmMessage,
- data,
- msg,
- winners as []
- )
- )
- .setColor("RANDOM")
- .setTimestamp()
- .setThumbnail(msg.guild.iconURL({ dynamic: true }))
- .setFooter({ text: "Made by Cath Team" });
- (winners as []).forEach(user => {
- message.guild.members.cache.get(user).send({ embeds: [dmEmbed] });
- });
- }
-
- const embed = msg.embeds[0];
- embed.description = this.replacePlaceholders(
- this.GiveawayMessages.giveawayDescription,
- data,
- msg,
- winners as []
- );
- msg.edit({ embeds: [embed] }).catch(err => console.log(err));
- data.Ended = true;
- data.save().catch(err => {
- console.log(err);
- });
- this.editButtons(message.client, data);
- }, time);
- }
- private gotoGiveaway(data) {
- if (!data) throw new CathError("Missing 'data'");
- const link = `https://discord.com/channels/${data.Guild}/${data.Channel}/${data.Message}`;
- const button = new MessageButton()
- .setLabel("Giveaway")
- .setStyle("LINK")
- .setURL(link);
- return button;
- }
- private async endByButton(
- client: Client,
- Message: Snowflake,
- button: ButtonInteraction
- ) {
- if (!client) throw new CathError("Missing 'client'");
- if (!Message) throw new CathError("Missing 'Message'");
- if (!button) throw new CathError("Missing 'button'");
- const data = await this.getByMessage(Message);
- const msg = await (
- client.guilds.cache
- .get(data.Guild)
- .channels.cache.get(data.Channel) as TextChannel
- ).messages.fetch(Message);
- const res = await this.end(msg, data, msg);
- if (res == "ENDED")
- await button.followUp({
- content: this.replacePlaceholders(
- this.GiveawayMessages.alreadyEnded,
- data,
- msg
- ),
- });
- }
-
- public async end(message: Message, data, giveawaymsg: Message) {
- if (!message) throw new CathError("Missing 'Message'");
- if (!data) throw new CathError("Missing 'data'");
- if (!giveawaymsg) throw new CathError("Missing 'Message'");
- const newData = await this.getByMessage(data.Message);
- if (newData.Ended) return "ENDED";
- const winners = await this.choose(data.Winners, message.id, message);
- const msg = await (
- message.client.guilds.cache
- .get(data.Guild)
- .channels.cache.get(data.Channel) as TextChannel
- ).messages.fetch(data.Message);
-
- if (!winners) {
- message.channel.send(
- this.replacePlaceholders(this.GiveawayMessages.noWinner, newData, msg)
- );
- data.Ended = true;
- await data.save();
- const embed = giveawaymsg.embeds[0];
- embed.description = this.replacePlaceholders(
- this.GiveawayMessages.giveawayDescription,
- newData,
- msg
- );
- embed.title = "Status: Ended! 🎉";
- giveawaymsg.edit({ embeds: [embed] }).catch(err => console.log(err));
- this.editButtons(message.client, data);
- return "NO_WINNERS";
- }
- message.channel.send(
- this.replacePlaceholders(
- this.GiveawayMessages.winMessage,
- newData,
- msg,
- winners as []
- )
- );
- if (this.GiveawayMessages.dmWinner) {
- const dmEmbed = new MessageEmbed()
- .setTitle("You Won!")
- .setDescription(
- this.replacePlaceholders(
- this.GiveawayMessages.dmMessage,
- newData,
- msg,
- winners as []
- )
- )
- .setColor("RANDOM")
- .setTimestamp()
- .setThumbnail(msg.guild.iconURL({ dynamic: true }))
- .setFooter({ text: "Made by Cath Team" });
- (winners as []).forEach(user => {
- message.guild.members.cache
- .get(user)
- .send({ embeds: [dmEmbed] })
- .catch();
- });
- }
-
- const embed = giveawaymsg.embeds[0];
- embed.description = this.replacePlaceholders(
- this.GiveawayMessages.giveawayDescription,
- data,
- msg,
- winners as []
- );
- embed.title = "Status: Ended! 🎉";
- giveawaymsg.edit({ embeds: [embed] }).catch(err => console.log(err));
- data.Ended = true;
- data.save().catch(err => {
- console.log(err);
- });
- this.editButtons(message.client, data);
- }
- public async reroll(client: Client, Message: Snowflake, message: Message) {
- if (!client) throw new CathError("Missing 'client'");
- if (!Message) throw new CathError("Missing 'Message'");
- const data = await this.getByMessage(Message);
- const msg = await (
- client.guilds.cache
- .get(data.Guild)
- .channels.cache.get(data.Channel) as TextChannel
- ).messages.fetch(Message);
- const embed = message.embeds[0];
- embed.title = "Status: Rerolled! 🎉";
- message.edit({ embeds: [embed] }).catch(err => console.log(err));
- const chosen = await this.choose(1, Message, message);
- if (!chosen) return [];
- const dmEmbed = new MessageEmbed()
- .setTitle("You Won!")
- .setDescription(
- this.replacePlaceholders(
- this.GiveawayMessages.dmMessage,
- data,
- msg,
- chosen as []
- )
- )
- .setColor("RANDOM")
- .setTimestamp()
- .setThumbnail(msg.guild.iconURL({ dynamic: true }))
- .setFooter({ text: "Made by Cath Team" });
- (chosen as []).forEach(user => {
- client.users.cache.get(user).send({ embeds: [dmEmbed] });
- });
- return chosen;
- }
- public async getByMessage(Message: Snowflake) {
- const doc = await this.schema.findOne({ Message: Message });
- if (!doc) return;
- return doc;
- }
- public async start(client: Client) {
- await this.schema.find({ Ended: false }).then(data => {
- setTimeout(async () => {
- data.forEach(async e => {
- const guild = await client.guilds.fetch(e.Guild);
- if (!guild) await e.delete();
- const channel = guild.channels.cache.get(e.Channel) as TextChannel;
- if (!channel) await e.delete();
- const msg = await channel.messages.fetch(e.Message).catch();
- if (!msg) await e.delete();
- this.startTimer(msg, e);
- });
- }, 10000);
- });
- if (this.GiveawayMessages.editParticipants) {
- setInterval(async () => {
- const docs = await this.schema.find({ Ended: false });
- for (let i = 0; i < docs.length; i++) {
- const guild = client.guilds.cache.get(docs[i].Guild);
- if (!guild) return;
- const channel = (await guild.channels.fetch(
- docs[i].Channel
- )) as TextChannel;
- if (!channel) return;
- const msg = await channel.messages.fetch(docs[i].Message);
- if (!msg) return;
- const embed = msg.embeds[0];
- const req = docs[i].Requirements.Enabled
- ? docs[i].Requirements.Roles.map(x => `<@&${x}>`).join(", ")
- : "None!";
- embed.description = `${
- this.GiveawayMessages.toParticipate
- }\n${this.GiveawayMessages.giveawayDescription
- .replace(/{invites}/g, docs[i].Invites.toString())
- .replace(/{requirements}/g, req)
- .replace(/{hostedBy}/g, `<@!${docs[i].HostBy}>`)
- .replace(/{award}/g, docs[i].Award)
- .replace(/{winners}/g, docs[i].Winners.toString())
- .replace(
- /{totalParticipants}/g,
- docs[i].Clickers.length.toString()
- )}`;
- msg.edit({ embeds: [embed] });
- }
- }, 10 * 1000);
- }
- }
-
- private replacePlaceholders(
- string: string,
- data: GiveawaySchema,
- msg: Message,
- winners = []
- ) {
- const newString = string
- .replace(/{invites}/g, data.Invites.toString())
- .replace(
- /{requirements}/g,
- data.Requirements.Enabled
- ? data.Requirements.Roles.map(x => `<@&${x}>`).join(", ")
- : "None!"
- )
- .replace(/{guildName}/g, msg.guild.name)
- .replace(/{totalParticipants}/g, data.Clickers.length.toString())
- .replace(/{award}/g, data.Award)
- .replace(
- /{giveawayURL}/g,
- `https://discord.com/channels/${msg.guild.id}/${msg.channel.id}/${data.Message}`
- )
- .replace(
- /{hostedBy}/g,
- msg.guild.members.cache.get(data.HostBy).toString()
- )
- .replace(
- /{winners}/g,
- winners.length > 0
- ? winners.map(winner => `<@${winner}>`).join(", ")
- : "None" || "None"
- );
- return newString;
- }
-}
+import mongoose, { Schema, model } from "mongoose";
+import {
+ Client,
+ Snowflake,
+ Message,
+ MessageActionRow,
+ MessageButton,
+ MessageEmbed,
+ TextChannel,
+ GuildMember,
+ ButtonInteraction,
+} from "discord.js";
+import { CathError } from "../Error/CathError";
+import {
+ GiveawaySchema,
+ GiveawaysClientOptions,
+ DefaultGiveawayMessages,
+ InviteSchema,
+} from "./giveaway.interface";
+import { parseString } from "../functions/ms";
+export class GiveawaysClient {
+ public inviteschema = model(
+ "cath-invite",
+ new Schema({
+ User: { type: String, required: true },
+ Invites: { type: Object, required: true },
+ })
+ );
+ public schema = model(
+ "cath-giveaways",
+ new Schema({
+ Guild: {
+ type: String,
+ required: true,
+ },
+ Channel: {
+ type: String,
+ required: true,
+ },
+ Message: {
+ type: String,
+ required: true,
+ },
+ HostBy: {
+ type: String,
+ required: true,
+ },
+ End: {
+ type: Number,
+ required: true,
+ },
+ Start: {
+ type: Number,
+ required: true,
+ },
+ Award: {
+ type: String,
+ required: true,
+ },
+ Winners: {
+ type: Number,
+ required: true,
+ },
+ Ended: {
+ type: Boolean,
+ default: false,
+ },
+ Invites: {
+ type: Number,
+ required: true,
+ default: 0,
+ },
+ Requirements: {
+ type: Object,
+ default: { Enabled: Boolean, Roles: [] },
+ },
+ Clickers: {
+ type: Array,
+ default: [],
+ },
+ })
+ );
+ public client: Client;
+ public GiveawayMessages: DefaultGiveawayMessages;
+ public MongooseConnectionURI: string;
+ /**
+ * @name GiveawaysClient
+ * @kind constructor
+ * @param {GiveawaysClientOptions}options
+ */
+
+ constructor(options: GiveawaysClientOptions) {
+ this.GiveawayMessages = options.GiveawayMessages || this.GiveawayMessages;
+ this.client = options.client;
+ this.MongooseConnectionURI = options.MongooseConnectionURI;
+ mongoose
+ .connect(this.MongooseConnectionURI, {
+ useNewUrlParser: true,
+ useUnifiedTopology: true,
+ })
+ .then(() => console.log("Connected to Giveaway Database"))
+ .catch(e => {
+ throw new CathError(e);
+ });
+ this.client.on("interactionCreate", async interaction => {
+ if (interaction.isButton()) {
+ let win = "" || [];
+ let L = 0;
+ let no = false;
+ if (!interaction.guild) return;
+ await (interaction.member as GuildMember).fetch();
+ const id = interaction.customId;
+ if (id.startsWith("g")) {
+ const tag = id.split("_");
+ if (tag[0] === "genter") {
+ const data = await this.schema.findOne({
+ Message: interaction.message.id,
+ });
+ if (data.Invites > 0) {
+ const invitedata = await this.inviteschema.findOne({
+ User: (interaction.member as GuildMember).id,
+ });
+ if (!invitedata) {
+ await interaction.reply({
+ content: "You have no invites, you can't enter",
+ ephemeral: true,
+ });
+ } else {
+ L = invitedata.Invites.map(o => o.Uses).reduce((acc, cur) => {
+ return acc + cur;
+ });
+ if (data.Invites >= L) {
+ await interaction.reply({
+ content: "You have not enough invites, you can't enter",
+ ephemeral: true,
+ });
+ no = true;
+ }
+ }
+ }
+ if (data.Requirements.Enabled) {
+ if (data.Requirements.Roles.length) {
+ const roles = data.Requirements.Roles.map(x =>
+ (interaction.message as Message).guild.members.cache
+ .get(interaction.user.id)
+ .roles.cache.get(x)
+ );
+ if (!roles[0]) {
+ const requiredRoles = (
+ interaction.message as Message
+ ).guild.roles.cache
+ .filter(x => data.Requirements.Roles.includes(x.id))
+ .filter(
+ x =>
+ !(interaction.message as Message).guild.members.cache
+ .get(interaction.user.id)
+ .roles.cache.get(x.id)
+ )
+ .map(x => `\`${x.name}\``)
+ .join(", ");
+ try {
+ await interaction.reply({
+ content: this.GiveawayMessages.nonoRole.replace(
+ /{requiredRoles}/g,
+ requiredRoles
+ ),
+ });
+ } catch (e) {
+ await interaction.followUp({
+ content: this.GiveawayMessages.nonoRole.replace(
+ /{requiredRoles}/g,
+ requiredRoles
+ ),
+ });
+ }
+ }
+ }
+ }
+ if (!data.Clickers.includes(interaction.user.id) && !no) {
+ data.Clickers.push(interaction.user.id);
+ data.save();
+ try {
+ await interaction.reply({
+ content: this.GiveawayMessages.newParticipant.replace(
+ /{totalParticipants}/g,
+ data.Clickers.length.toString()
+ ),
+ });
+ } catch (e) {
+ await interaction.followUp({
+ content: this.GiveawayMessages.newParticipant.replace(
+ /{totalParticipants}/g,
+ data.Clickers.length.toString()
+ ),
+ });
+ }
+ } else if (data.Clickers.includes(interaction.user.id) && !no) {
+ await interaction.followUp({
+ content: this.GiveawayMessages.alreadyParticipated,
+ });
+ } else if (!data.Clickers.includes(interaction.user.id) && no) {
+ } else if (data.Clickers.includes(interaction.user.id) && no) {
+ }
+ }
+ if (tag[0] === "greroll") {
+ if (interaction.user.id !== tag[1])
+ await interaction.reply({
+ content: "Only the host can reroll the giveaway",
+ });
+ try {
+ win = await this.reroll(
+ this.client,
+ interaction.message.id,
+ interaction.message as Message
+ );
+ } catch (err) {
+ console.log(err);
+ await interaction.reply({
+ content: "⚠️ **Unable To Find That Giveaway**",
+ });
+ }
+ if (!win.length)
+ interaction.channel.send(this.GiveawayMessages.noParticipants);
+ else {
+ await interaction.reply({
+ content: "Rerolled",
+ ephemeral: true,
+ });
+ interaction.channel.send({
+ content: this.GiveawayMessages.rerolledMessage.replace(
+ /{winner}/g,
+ `<@${win}>`
+ ),
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Giveaway")
+ .setURL(
+ `https://discord.com/channels/${interaction.guild.id}/${interaction.channel.id}/${interaction.message.id}`
+ )
+ .setStyle("LINK"),
+ ]),
+ ],
+ });
+ }
+ }
+ if (tag[0] === "gend") {
+ if (interaction.user.id !== tag[1])
+ await interaction.reply({
+ content: "You Cannot End This Giveaway, Only The Host Can",
+ });
+ await interaction.reply({ content: "Ended", ephemeral: true });
+ await this.endByButton(
+ this.client,
+ interaction.message.id,
+ interaction
+ );
+ }
+ }
+ }
+ });
+ }
+
+ private getButtons(host: string) {
+ const reroll = new MessageButton()
+ .setLabel("Reroll")
+ .setStyle("SECONDARY")
+ .setCustomId(`greroll_${host}`)
+ .setDisabled(true);
+
+ const end = new MessageButton()
+ .setLabel("End")
+ .setStyle("DANGER")
+ .setCustomId(`gend_${host}`);
+
+ const enter = new MessageButton()
+ .setLabel("Enter")
+ .setStyle("SUCCESS")
+ .setCustomId(`genter_${host}`);
+
+ const b = [enter, end, reroll];
+ return b;
+ }
+
+ private async choose(winners: number, msgid: Snowflake, message: Message) {
+ const data = await this.getByMessage(msgid);
+ const final = [];
+ if (data.Requirements.Enabled && data.Invites == 0) {
+ const c = data.Clickers.filter(x =>
+ this.checkRoles(x, data.Requirements.Roles, message)
+ );
+ for (let i = 0; i < winners; i++) {
+ if (!c.length) return final[0] ? final : [];
+ const win = c[Math.floor(Math.random() * c.length)];
+ if (final.includes(win)) break;
+ if (!win) return final[0] ? final : [];
+ final.push(win);
+ }
+ } else {
+ for (let i = 0; i < winners; i++) {
+ if (!data.Clickers.length) return final[0] ? final : [];
+ const win =
+ data.Clickers[Math.floor(Math.random() * data.Clickers.length)];
+ if (final.includes(win)) break;
+ if (!win) return final[0] ? final : [];
+ final.push(win);
+ }
+ }
+ return final[0] ? final : [];
+ }
+
+ private checkRoles(
+ userID: Snowflake,
+ roleIDs: Snowflake[],
+ message: Message
+ ): Boolean {
+ let res = null;
+ roleIDs.forEach(roleID => {
+ const role = message.guild.roles.cache.get(roleID);
+ if (!message.guild.members.cache.get(userID).roles.cache.get(role.id))
+ res = false;
+ });
+ if (res == false) return false;
+ else return true;
+ }
+
+ private async editButtons(client: Client, data: GiveawaySchema) {
+ const m = await (
+ client.guilds.cache
+ .get(data.Guild)
+ .channels.cache.get(data.Channel) as TextChannel
+ ).messages.fetch(data.Message);
+ const bs = await this.getButtons(data.HostBy);
+ bs.find(x => x.label == "Enter")
+ .setDisabled()
+ .setStyle("SECONDARY");
+ bs.find(x => x.label == "End")
+ .setDisabled()
+ .setStyle("SECONDARY");
+ bs.find(x => x.label == "Reroll")
+ .setDisabled(false)
+ .setStyle("SUCCESS");
+ const row = new MessageActionRow().addComponents(bs);
+ m.edit({
+ components: [row],
+ embeds: m.embeds,
+ }).catch(e => {
+ throw new CathError(e);
+ });
+ }
+
+ private async giveawayEmbed(
+ client: Client,
+ status: string,
+ { host, prize, endAfter, invites, winners, requirements }
+ ) {
+ const hostedBy =
+ client.users.cache.get(host) ||
+ (await client.users.fetch(host).catch(() => null));
+ let req = "";
+ if (requirements.Roles)
+ req += `\n Role(s): ${requirements.Roles.map(x => `<@&${x}>`).join(
+ ", "
+ )}`;
+ if (requirements.weeklyamari)
+ req += `\n Weekly Amari: \`${requirements.weeklyamari}\``;
+ if (requirements.amarilevel)
+ req += `\n Amari Level: \`${requirements.amarilevel}\``;
+ const embed = new MessageEmbed()
+ .setTitle(`Status: ${status}! 🎉`)
+ .setDescription(
+ `${
+ this.GiveawayMessages.toParticipate
+ }\n${this.GiveawayMessages.giveawayDescription
+ .replace(/{invites}/g, invites ? invites : "0")
+ .replace(/{requirements}/g, req)
+ .replace(/{hostedBy}/g, hostedBy || "Can't find the user")
+ .replace(/{award}/g, prize)
+ .replace(/{winners}/g, winners)
+ .replace(/{totalParticipants}/g, "0")}`
+ )
+ .setColor("RANDOM")
+ .setFooter({
+ text: "Ends",
+ iconURL: this.GiveawayMessages.giveawayFooterImage,
+ })
+ .setTimestamp(Date.now() + parseString(endAfter));
+ return embed;
+ }
+
+ public async create(
+ client: Client,
+ { prize, host, winners, endAfter, invites, requirements, Channel }
+ ) {
+ if (!client)
+ throw new CathError("client wasnt provided while creating giveaway!");
+ if (!prize)
+ throw new CathError("prize wasnt provided while creating giveaway!");
+ if (typeof prize !== "string")
+ throw new TypeError("prize should be a string");
+ if (!host)
+ throw new CathError("host wasnt provided while creating giveaway");
+ if (!winners)
+ throw new CathError(
+ "winner count wasnt provided while creating giveaway"
+ );
+ if (isNaN(winners)) throw new TypeError("winners should be a Number");
+ if (!endAfter)
+ throw new CathError("time wasnt provided while creating giveaway");
+ if (typeof endAfter !== "string")
+ throw new TypeError("endAfter should be a string");
+ if (
+ invites < 0 &&
+ invites == null &&
+ invites == undefined &&
+ typeof invites !== "number"
+ ) {
+ throw new CathError("invites wasnt provided while creating giveaway");
+ }
+ if (!Channel)
+ throw new CathError("channel ID wasnt provided while creating giveaway");
+ const status = "In Progress";
+ const msg = await (client.channels.cache.get(Channel) as TextChannel).send({
+ content: this.GiveawayMessages.giveaway,
+ components: [new MessageActionRow().addComponents(this.getButtons(host))],
+ embeds: [
+ await this.giveawayEmbed(client, status, {
+ host,
+ prize,
+ endAfter,
+ invites,
+ winners,
+ requirements,
+ }),
+ ],
+ });
+
+ const data = await new this.schema({
+ Message: msg.id,
+ Channel: Channel,
+ Guild: msg.guild.id,
+ HostBy: host,
+ Winners: winners,
+ Award: prize,
+ Start: Date.now(),
+ End: Date.now() + parseString(endAfter),
+ Invites: invites,
+ Requirements: requirements,
+ }).save();
+ await this.startTimer(msg, data);
+ }
+
+ private async startTimer(message: Message, data, instant = false) {
+ if (!message) throw new CathError("Missing 'message'");
+ if (!data) throw new CathError("Missing 'data'");
+ const msg = await (
+ message.guild.channels.cache.get(data.Channel) as TextChannel
+ ).messages.fetch(data.Message);
+ await msg.fetch();
+ const time = instant ? 0 : data.End - Date.now();
+ setTimeout(async () => {
+ const winners = await this.choose(data.winners, data.Message, message);
+ if (!winners) {
+ msg.channel.send({
+ content: this.replacePlaceholders(
+ this.GiveawayMessages.noWinner,
+ data,
+ msg
+ ),
+ });
+ data.Ended = true;
+ data.save();
+ const embed = msg.embeds[0];
+ embed.description = this.replacePlaceholders(
+ this.GiveawayMessages.giveawayDescription,
+ data,
+ msg
+ );
+ msg.edit({ embeds: [embed] });
+ this.editButtons(message.client, data);
+ return "NO_WINNERS";
+ }
+ message.channel.send({
+ content: this.replacePlaceholders(
+ this.GiveawayMessages.winMessage,
+ await this.getByMessage(data.Message),
+ msg,
+ winners as []
+ ),
+ });
+
+ if (this.GiveawayMessages.dmWinner) {
+ const dmEmbed = new MessageEmbed()
+ .setTitle("You Won!")
+ .setDescription(
+ this.replacePlaceholders(
+ this.GiveawayMessages.dmMessage,
+ data,
+ msg,
+ winners as []
+ )
+ )
+ .setColor("RANDOM")
+ .setTimestamp()
+ .setThumbnail(msg.guild.iconURL({ dynamic: true }))
+ .setFooter({ text: "Made by Cath Team" });
+ (winners as []).forEach(user => {
+ message.guild.members.cache.get(user).send({ embeds: [dmEmbed] });
+ });
+ }
+
+ const embed = msg.embeds[0];
+ embed.description = this.replacePlaceholders(
+ this.GiveawayMessages.giveawayDescription,
+ data,
+ msg,
+ winners as []
+ );
+ msg.edit({ embeds: [embed] }).catch(err => console.log(err));
+ data.Ended = true;
+ data.save().catch(err => {
+ console.log(err);
+ });
+ this.editButtons(message.client, data);
+ }, time);
+ }
+ private gotoGiveaway(data) {
+ if (!data) throw new CathError("Missing 'data'");
+ const link = `https://discord.com/channels/${data.Guild}/${data.Channel}/${data.Message}`;
+ const button = new MessageButton()
+ .setLabel("Giveaway")
+ .setStyle("LINK")
+ .setURL(link);
+ return button;
+ }
+ private async endByButton(
+ client: Client,
+ Message: Snowflake,
+ button: ButtonInteraction
+ ) {
+ if (!client) throw new CathError("Missing 'client'");
+ if (!Message) throw new CathError("Missing 'Message'");
+ if (!button) throw new CathError("Missing 'button'");
+ const data = await this.getByMessage(Message);
+ const msg = await (
+ client.guilds.cache
+ .get(data.Guild)
+ .channels.cache.get(data.Channel) as TextChannel
+ ).messages.fetch(Message);
+ const res = await this.end(msg, data, msg);
+ if (res == "ENDED")
+ await button.followUp({
+ content: this.replacePlaceholders(
+ this.GiveawayMessages.alreadyEnded,
+ data,
+ msg
+ ),
+ });
+ }
+
+ public async end(message: Message, data, giveawaymsg: Message) {
+ if (!message) throw new CathError("Missing 'Message'");
+ if (!data) throw new CathError("Missing 'data'");
+ if (!giveawaymsg) throw new CathError("Missing 'Message'");
+ const newData = await this.getByMessage(data.Message);
+ if (newData.Ended) return "ENDED";
+ const winners = await this.choose(data.Winners, message.id, message);
+ const msg = await (
+ message.client.guilds.cache
+ .get(data.Guild)
+ .channels.cache.get(data.Channel) as TextChannel
+ ).messages.fetch(data.Message);
+
+ if (!winners) {
+ message.channel.send(
+ this.replacePlaceholders(this.GiveawayMessages.noWinner, newData, msg)
+ );
+ data.Ended = true;
+ await data.save();
+ const embed = giveawaymsg.embeds[0];
+ embed.description = this.replacePlaceholders(
+ this.GiveawayMessages.giveawayDescription,
+ newData,
+ msg
+ );
+ embed.title = "Status: Ended! 🎉";
+ giveawaymsg.edit({ embeds: [embed] }).catch(err => console.log(err));
+ this.editButtons(message.client, data);
+ return "NO_WINNERS";
+ }
+ message.channel.send(
+ this.replacePlaceholders(
+ this.GiveawayMessages.winMessage,
+ newData,
+ msg,
+ winners as []
+ )
+ );
+ if (this.GiveawayMessages.dmWinner) {
+ const dmEmbed = new MessageEmbed()
+ .setTitle("You Won!")
+ .setDescription(
+ this.replacePlaceholders(
+ this.GiveawayMessages.dmMessage,
+ newData,
+ msg,
+ winners as []
+ )
+ )
+ .setColor("RANDOM")
+ .setTimestamp()
+ .setThumbnail(msg.guild.iconURL({ dynamic: true }))
+ .setFooter({ text: "Made by Cath Team" });
+ (winners as []).forEach(user => {
+ message.guild.members.cache
+ .get(user)
+ .send({ embeds: [dmEmbed] })
+ .catch();
+ });
+ }
+
+ const embed = giveawaymsg.embeds[0];
+ embed.description = this.replacePlaceholders(
+ this.GiveawayMessages.giveawayDescription,
+ data,
+ msg,
+ winners as []
+ );
+ embed.title = "Status: Ended! 🎉";
+ giveawaymsg.edit({ embeds: [embed] }).catch(err => console.log(err));
+ data.Ended = true;
+ data.save().catch(err => {
+ console.log(err);
+ });
+ this.editButtons(message.client, data);
+ }
+ public async reroll(client: Client, Message: Snowflake, message: Message) {
+ if (!client) throw new CathError("Missing 'client'");
+ if (!Message) throw new CathError("Missing 'Message'");
+ const data = await this.getByMessage(Message);
+ const msg = await (
+ client.guilds.cache
+ .get(data.Guild)
+ .channels.cache.get(data.Channel) as TextChannel
+ ).messages.fetch(Message);
+ const embed = message.embeds[0];
+ embed.title = "Status: Rerolled! 🎉";
+ message.edit({ embeds: [embed] }).catch(err => console.log(err));
+ const chosen = await this.choose(1, Message, message);
+ if (!chosen) return [];
+ const dmEmbed = new MessageEmbed()
+ .setTitle("You Won!")
+ .setDescription(
+ this.replacePlaceholders(
+ this.GiveawayMessages.dmMessage,
+ data,
+ msg,
+ chosen as []
+ )
+ )
+ .setColor("RANDOM")
+ .setTimestamp()
+ .setThumbnail(msg.guild.iconURL({ dynamic: true }))
+ .setFooter({ text: "Made by Cath Team" });
+ (chosen as []).forEach(user => {
+ client.users.cache.get(user).send({ embeds: [dmEmbed] });
+ });
+ return chosen;
+ }
+ public async getByMessage(Message: Snowflake) {
+ const doc = await this.schema.findOne({ Message: Message });
+ if (!doc) return;
+ return doc;
+ }
+ public async start(client: Client) {
+ await this.schema.find({ Ended: false }).then(data => {
+ setTimeout(async () => {
+ data.forEach(async e => {
+ const guild = await client.guilds.fetch(e.Guild);
+ if (!guild) await e.delete();
+ const channel = guild.channels.cache.get(e.Channel) as TextChannel;
+ if (!channel) await e.delete();
+ const msg = await channel.messages.fetch(e.Message).catch();
+ if (!msg) await e.delete();
+ this.startTimer(msg, e);
+ });
+ }, 10000);
+ });
+ if (this.GiveawayMessages.editParticipants) {
+ setInterval(async () => {
+ const docs = await this.schema.find({ Ended: false });
+ for (let i = 0; i < docs.length; i++) {
+ const guild = client.guilds.cache.get(docs[i].Guild);
+ if (!guild) return;
+ const channel = (await guild.channels.fetch(
+ docs[i].Channel
+ )) as TextChannel;
+ if (!channel) return;
+ const msg = await channel.messages.fetch(docs[i].Message);
+ if (!msg) return;
+ const embed = msg.embeds[0];
+ const req = docs[i].Requirements.Enabled
+ ? docs[i].Requirements.Roles.map(x => `<@&${x}>`).join(", ")
+ : "None!";
+ embed.description = `${
+ this.GiveawayMessages.toParticipate
+ }\n${this.GiveawayMessages.giveawayDescription
+ .replace(/{invites}/g, docs[i].Invites.toString())
+ .replace(/{requirements}/g, req)
+ .replace(/{hostedBy}/g, `<@!${docs[i].HostBy}>`)
+ .replace(/{award}/g, docs[i].Award)
+ .replace(/{winners}/g, docs[i].Winners.toString())
+ .replace(
+ /{totalParticipants}/g,
+ docs[i].Clickers.length.toString()
+ )}`;
+ msg.edit({ embeds: [embed] });
+ }
+ }, 10 * 1000);
+ }
+ }
+
+ private replacePlaceholders(
+ string: string,
+ data: GiveawaySchema,
+ msg: Message,
+ winners = []
+ ) {
+ const newString = string
+ .replace(/{invites}/g, data.Invites.toString())
+ .replace(
+ /{requirements}/g,
+ data.Requirements.Enabled
+ ? data.Requirements.Roles.map(x => `<@&${x}>`).join(", ")
+ : "None!"
+ )
+ .replace(/{guildName}/g, msg.guild.name)
+ .replace(/{totalParticipants}/g, data.Clickers.length.toString())
+ .replace(/{award}/g, data.Award)
+ .replace(
+ /{giveawayURL}/g,
+ `https://discord.com/channels/${msg.guild.id}/${msg.channel.id}/${data.Message}`
+ )
+ .replace(
+ /{hostedBy}/g,
+ msg.guild.members.cache.get(data.HostBy).toString()
+ )
+ .replace(
+ /{winners}/g,
+ winners.length > 0
+ ? winners.map(winner => `<@${winner}>`).join(", ")
+ : "None" || "None"
+ );
+ return newString;
+ }
+}
diff --git a/src/GiveawaysClient/index.ts b/src/GiveawaysClient/index.ts
index 95eadeb..e22ea63 100644
--- a/src/GiveawaysClient/index.ts
+++ b/src/GiveawaysClient/index.ts
@@ -1,6 +1,6 @@
-export { GiveawaysClient } from "./giveaway";
-export {
- GiveawaySchema,
- GiveawaysClientOptions,
- DefaultGiveawayMessages,
-} from "./giveaway.interface";
+export { GiveawaysClient } from "./giveaway";
+export {
+ GiveawaySchema,
+ GiveawaysClientOptions,
+ DefaultGiveawayMessages,
+} from "./giveaway.interface";
diff --git a/src/ImageClient/image.ts b/src/ImageClient/image.ts
index 96fc399..b5952ec 100644
--- a/src/ImageClient/image.ts
+++ b/src/ImageClient/image.ts
@@ -1,67 +1,67 @@
-import { config } from "../";
-/**
- * @name ImageClient
- * @kind constructor
- */
-export class ImageClient {
- constructor() {}
- private endpoint(end: string, ava: string, ava1?: string, ava2?: string) {
- if (ava && ava1 && !ava2)
- return `${config.api}/api/v1/image/${end}?image=${ava}&image2=${ava1}`;
- else if (ava && ava1 && ava2)
- return `${config.api}/api/v1/image/${end}?image=${ava}&image2=${ava1}&image3=${ava2}`;
- else return `${config.api}/api/v1/image/${end}?image=${ava}`;
- }
- public busted(AvatarURL: string) {
- return this.endpoint("busted", AvatarURL);
- }
- public communism(AvatarURL: string) {
- return this.endpoint("communism", AvatarURL);
- }
- public gun(AvatarURL: string) {
- return this.endpoint("gun", AvatarURL);
- }
- public mask(AvatarURL: string) {
- return this.endpoint("mask", AvatarURL);
- }
- public whodidthis(AvatarURL: string) {
- return this.endpoint("whodidthis", AvatarURL);
- }
- public pray(AvatarURL: string) {
- return this.endpoint("pray", AvatarURL);
- }
- public pressplay(AvatarURL: string) {
- return this.endpoint("pressplay", AvatarURL);
- }
- public vr(AvatarURL: string) {
- return this.endpoint("vr", AvatarURL);
- }
- public rifleshoot(AvatarURL: string) {
- return this.endpoint("rifleshoot", AvatarURL);
- }
- public bestmeme(AvatarURL: string) {
- return this.endpoint("bestmeme", AvatarURL);
- }
- public robert(AvatarURL: string) {
- return this.endpoint("robert", AvatarURL);
- }
- public saveonlyone(
- AvatarURL1: string,
- AvatarURL2: string,
- AvatarURL3: string
- ) {
- return this.endpoint("saveonlyone", AvatarURL1, AvatarURL2, AvatarURL3);
- }
- public alone(AvatarURL: string) {
- return this.endpoint("alone", AvatarURL);
- }
- public toilet(AvatarURL: string) {
- return this.endpoint("toilet", AvatarURL);
- }
- public moment(AvatarURL: string) {
- return this.endpoint("moment", AvatarURL);
- }
- public awesome(AvatarURL: string) {
- return this.endpoint("awesome", AvatarURL);
- }
-}
+import { config } from "../";
+/**
+ * @name ImageClient
+ * @kind constructor
+ */
+export class ImageClient {
+ constructor() {}
+ private endpoint(end: string, ava: string, ava1?: string, ava2?: string) {
+ if (ava && ava1 && !ava2)
+ return `${config.api}/api/v1/image/${end}?image=${ava}&image2=${ava1}`;
+ else if (ava && ava1 && ava2)
+ return `${config.api}/api/v1/image/${end}?image=${ava}&image2=${ava1}&image3=${ava2}`;
+ else return `${config.api}/api/v1/image/${end}?image=${ava}`;
+ }
+ public busted(AvatarURL: string) {
+ return this.endpoint("busted", AvatarURL);
+ }
+ public communism(AvatarURL: string) {
+ return this.endpoint("communism", AvatarURL);
+ }
+ public gun(AvatarURL: string) {
+ return this.endpoint("gun", AvatarURL);
+ }
+ public mask(AvatarURL: string) {
+ return this.endpoint("mask", AvatarURL);
+ }
+ public whodidthis(AvatarURL: string) {
+ return this.endpoint("whodidthis", AvatarURL);
+ }
+ public pray(AvatarURL: string) {
+ return this.endpoint("pray", AvatarURL);
+ }
+ public pressplay(AvatarURL: string) {
+ return this.endpoint("pressplay", AvatarURL);
+ }
+ public vr(AvatarURL: string) {
+ return this.endpoint("vr", AvatarURL);
+ }
+ public rifleshoot(AvatarURL: string) {
+ return this.endpoint("rifleshoot", AvatarURL);
+ }
+ public bestmeme(AvatarURL: string) {
+ return this.endpoint("bestmeme", AvatarURL);
+ }
+ public robert(AvatarURL: string) {
+ return this.endpoint("robert", AvatarURL);
+ }
+ public saveonlyone(
+ AvatarURL1: string,
+ AvatarURL2: string,
+ AvatarURL3: string
+ ) {
+ return this.endpoint("saveonlyone", AvatarURL1, AvatarURL2, AvatarURL3);
+ }
+ public alone(AvatarURL: string) {
+ return this.endpoint("alone", AvatarURL);
+ }
+ public toilet(AvatarURL: string) {
+ return this.endpoint("toilet", AvatarURL);
+ }
+ public moment(AvatarURL: string) {
+ return this.endpoint("moment", AvatarURL);
+ }
+ public awesome(AvatarURL: string) {
+ return this.endpoint("awesome", AvatarURL);
+ }
+}
diff --git a/src/ImageClient/index.ts b/src/ImageClient/index.ts
index 4a6710b..8914604 100644
--- a/src/ImageClient/index.ts
+++ b/src/ImageClient/index.ts
@@ -1 +1 @@
-export { ImageClient } from "./image";
+export { ImageClient } from "./image";
diff --git a/src/URLClient/index.ts b/src/URLClient/index.ts
index fc8b4cd..c05f7ff 100644
--- a/src/URLClient/index.ts
+++ b/src/URLClient/index.ts
@@ -1,2 +1,2 @@
-export { URLClient } from "./urlclient";
-export { URLData } from "./urlclient.interface";
+export { URLClient } from "./urlclient";
+export { URLData } from "./urlclient.interface";
diff --git a/src/URLClient/urlclient.interface.ts b/src/URLClient/urlclient.interface.ts
index 781c905..a936a26 100644
--- a/src/URLClient/urlclient.interface.ts
+++ b/src/URLClient/urlclient.interface.ts
@@ -1,3 +1,3 @@
-export interface URLData {
- url: String;
-}
+export interface URLData {
+ url: String;
+}
diff --git a/src/URLClient/urlclient.ts b/src/URLClient/urlclient.ts
index e11eb71..63754f6 100644
--- a/src/URLClient/urlclient.ts
+++ b/src/URLClient/urlclient.ts
@@ -1,33 +1,33 @@
-import axios from "axios";
-import { config } from "../";
-import { URLData } from "./urlclient.interface";
-import { CathError } from "../Error/CathError";
-/**
- * @name URLClient
- * @kind constructor
- */
-export class URLClient {
- constructor() {}
- /**
- * Sends the link of the URL
- * @return {Promise}
- * @param {String} shortName
- * @param {String} targetURL
- */
- public async createShortURL(
- shortName: string,
- targetURL: string
- ): Promise {
- if (!shortName) throw new CathError("Missing 'shortName' property");
- if (!targetURL) throw new CathError("Missing 'targetURL' property");
- const data = await axios
- .post(`${config.url}`, {
- shortUrl: shortName,
- fullUrl: targetURL,
- })
- .then(res => res.data);
- if (data?.name) {
- return data?.name;
- }
- }
-}
+import axios from "axios";
+import { config } from "../";
+import { URLData } from "./urlclient.interface";
+import { CathError } from "../Error/CathError";
+/**
+ * @name URLClient
+ * @kind constructor
+ */
+export class URLClient {
+ constructor() {}
+ /**
+ * Sends the link of the URL
+ * @return {Promise}
+ * @param {String} shortName
+ * @param {String} targetURL
+ */
+ public async createShortURL(
+ shortName: string,
+ targetURL: string
+ ): Promise {
+ if (!shortName) throw new CathError("Missing 'shortName' property");
+ if (!targetURL) throw new CathError("Missing 'targetURL' property");
+ const data = await axios
+ .post(`${config.url}`, {
+ shortUrl: shortName,
+ fullUrl: targetURL,
+ })
+ .then(res => res.data);
+ if (data?.name) {
+ return data?.name;
+ }
+ }
+}
diff --git a/src/config.ts b/src/config.ts
index 1a2aad9..c253d2b 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,12 +1,12 @@
-const config: ConfigURLS = {
- api: "https://api.night0721.me",
- code: "https://cdn.night0721.me/api/paste",
- url: "https://cdn.night0721.me/api/url",
-};
-
-interface ConfigURLS {
- api: string;
- code: string;
- url: string;
-}
-export { config, ConfigURLS };
+const config: ConfigURLS = {
+ api: "https://api.night0721.me",
+ code: "https://cdn.night0721.me/api/paste",
+ url: "https://cdn.night0721.me/api/url",
+};
+
+interface ConfigURLS {
+ api: string;
+ code: string;
+ url: string;
+}
+export { config, ConfigURLS };
diff --git a/src/functions/8ball.ts b/src/functions/8ball.ts
index 585cdda..4b01c61 100644
--- a/src/functions/8ball.ts
+++ b/src/functions/8ball.ts
@@ -1,11 +1,11 @@
-import axios from "axios";
-import { config } from "../";
-/**
- * Sends a 8ball response
- */
-export async function random8ball(): Promise {
- const data = await axios
- .get(`${config.api}/api/v1/fun/8ball`)
- .then(res => res.data);
- return data.answer;
-}
+import axios from "axios";
+import { config } from "../";
+/**
+ * Sends a 8ball response
+ */
+export async function random8ball(): Promise {
+ const data = await axios
+ .get(`${config.api}/api/v1/fun/8ball`)
+ .then(res => res.data);
+ return data.answer;
+}
diff --git a/src/functions/HHMMSS.ts b/src/functions/HHMMSS.ts
index 17ea3ce..e320ba9 100644
--- a/src/functions/HHMMSS.ts
+++ b/src/functions/HHMMSS.ts
@@ -1,21 +1,21 @@
-import { CathError } from "../Error/CathError";
-/**
- * Returns a string(00:00:00)
- */
-export function HHMMSS(str: string) {
- if (!str) throw new CathError("Missing 'str'");
- var sec_num = parseInt(str, 10);
- var hours = Math.floor(sec_num / 3600);
- var minutes = Math.floor((sec_num - hours * 3600) / 60);
- var seconds = sec_num - hours * 3600 - minutes * 60;
- if (hours < 10) {
- hours = 0 + hours;
- }
- if (minutes < 10) {
- minutes = 0 + minutes;
- }
- if (seconds < 10) {
- seconds = 0 + seconds;
- }
- return hours + ":" + minutes + ":" + seconds;
-}
+import { CathError } from "../Error/CathError";
+/**
+ * Returns a string(00:00:00)
+ */
+export function HHMMSS(str: string) {
+ if (!str) throw new CathError("Missing 'str'");
+ var sec_num = parseInt(str, 10);
+ var hours = Math.floor(sec_num / 3600);
+ var minutes = Math.floor((sec_num - hours * 3600) / 60);
+ var seconds = sec_num - hours * 3600 - minutes * 60;
+ if (hours < 10) {
+ hours = 0 + hours;
+ }
+ if (minutes < 10) {
+ minutes = 0 + minutes;
+ }
+ if (seconds < 10) {
+ seconds = 0 + seconds;
+ }
+ return hours + ":" + minutes + ":" + seconds;
+}
diff --git a/src/functions/bool.ts b/src/functions/bool.ts
index fe19454..b1383ea 100644
--- a/src/functions/bool.ts
+++ b/src/functions/bool.ts
@@ -1,8 +1,8 @@
-/**
- * Returns true/false
- */
-export function bool() {
- const arr = [true, false];
- const num = arr[Math.floor(Math.random() * arr.length)];
- return num;
-}
+/**
+ * Returns true/false
+ */
+export function bool() {
+ const arr = [true, false];
+ const num = arr[Math.floor(Math.random() * arr.length)];
+ return num;
+}
diff --git a/src/functions/cleanText.ts b/src/functions/cleanText.ts
index fbe453b..7e1dd06 100644
--- a/src/functions/cleanText.ts
+++ b/src/functions/cleanText.ts
@@ -1,12 +1,12 @@
-/**
- * Returns a string without " ` " or " @ "
- */
-export function cleanText(text: string): string {
- if (typeof text === "string") {
- return text
- .replace(/`/g, "`" + String.fromCharCode(8203))
- .replace(/@/g, "@" + String.fromCharCode(8203));
- } else {
- return text;
- }
-}
+/**
+ * Returns a string without " ` " or " @ "
+ */
+export function cleanText(text: string): string {
+ if (typeof text === "string") {
+ return text
+ .replace(/`/g, "`" + String.fromCharCode(8203))
+ .replace(/@/g, "@" + String.fromCharCode(8203));
+ } else {
+ return text;
+ }
+}
diff --git a/src/functions/confirmation.ts b/src/functions/confirmation.ts
index 5a792e6..d342235 100644
--- a/src/functions/confirmation.ts
+++ b/src/functions/confirmation.ts
@@ -1,19 +1,19 @@
-import { Message } from "discord.js";
-export async function confirmation(
- message: Message,
- author,
- validReactions = [],
- time = 60000
-) {
- try {
- for (const reaction of validReactions) await message.react(reaction);
- const filter = (reaction, user) =>
- validReactions.includes(reaction.emoji.name) && user.id === author.id;
-
- return message
- .awaitReactions({ filter, max: 1, time: time })
- .then(collected => collected.first() && collected.first().emoji.name);
- } catch (e) {
- console.log(e);
- }
-}
+import { Message } from "discord.js";
+export async function confirmation(
+ message: Message,
+ author,
+ validReactions = [],
+ time = 60000
+) {
+ try {
+ for (const reaction of validReactions) await message.react(reaction);
+ const filter = (reaction, user) =>
+ validReactions.includes(reaction.emoji.name) && user.id === author.id;
+
+ return message
+ .awaitReactions({ filter, max: 1, time: time })
+ .then(collected => collected.first() && collected.first().emoji.name);
+ } catch (e) {
+ console.log(e);
+ }
+}
diff --git a/src/functions/daysAgo.ts b/src/functions/daysAgo.ts
index 1b28cc8..03fe2d4 100644
--- a/src/functions/daysAgo.ts
+++ b/src/functions/daysAgo.ts
@@ -1,9 +1,9 @@
-import { CathError } from "../Error/CathError";
-
-export function daysAgo(date: Date) {
- if (!date) throw new CathError("Missing 'date'");
- let now = new Date();
- let diff = now.getTime() - date.getTime();
- let days = Math.floor(diff / 86400000);
- return days + (days == 1 ? " day" : " days") + " ago";
-}
+import { CathError } from "../Error/CathError";
+
+export function daysAgo(date: Date) {
+ if (!date) throw new CathError("Missing 'date'");
+ let now = new Date();
+ let diff = now.getTime() - date.getTime();
+ let days = Math.floor(diff / 86400000);
+ return days + (days == 1 ? " day" : " days") + " ago";
+}
diff --git a/src/functions/discord-activity.ts b/src/functions/discord-activity.ts
index f2cad7d..9c59ed8 100644
--- a/src/functions/discord-activity.ts
+++ b/src/functions/discord-activity.ts
@@ -1,80 +1,80 @@
-import { CathError } from "../Error/CathError";
-import axios from "axios";
-/**
- * Start a Discord Activity session
- * @example
- * const Cath = require("cath")
- * const client = new Client()
- * const d = await Cath.DiscordActivity({
- application: "youtube",
- channel_id: "901542111005012099",
- token: client.token,
- });
- message.channel.send({ content: d });
- */
-export async function DiscordActivity(options: DiscordActivityOptions) {
- const all = {
- youtube: "880218394199220334",
- youtubedev: "880218832743055411",
- poker: "755827207812677713",
- betrayal: "773336526917861400",
- fishing: "814288819477020702",
- chess: "832012774040141894",
- chessdev: "832012586023256104",
- lettertile: "879863686565621790",
- wordsnack: "879863976006127627",
- doodlecrew: "878067389634314250",
- awkword: "879863881349087252",
- spellcast: "852509694341283871",
- };
- if (!all[options.application]) {
- throw new CathError(
- "Application ID is not valid, if you want to see the list of applications, check the docs at https://cath.js.org/interfaces/Applications.html"
- );
- }
- if (!options.token) {
- throw new CathError("Missing 'token'");
- }
- if (!options.channel_id) {
- throw new CathError("Missing 'Channel ID'");
- }
- const data = await axios
- .post(
- `https://discord.com/api/v9/channels/${options.channel_id}/invites`,
- {
- max_age: 86400,
- max_uses: 0,
- target_application_id: all[options.application],
- target_type: 2,
- temporary: false,
- validate: null,
- },
- {
- headers: {
- Authorization: `Bot ${options.token}`,
- "Content-Type": "application/json",
- },
- }
- )
- .then(res => res.data);
- return `https://discord.com/invite/${data.code}`;
-}
-export interface DiscordActivityOptions {
- application: string;
- token: string;
- channel_id: string;
-}
-export interface Applications {
- youtube: "880218394199220334";
- youtubedev: "880218832743055411";
- poker: "755827207812677713";
- betrayal: "773336526917861400";
- fishing: "814288819477020702";
- chess: "832012774040141894";
- chessdev: "832012586023256104";
- lettertile: "879863686565621790";
- wordsnack: "879863976006127627";
- doodlecrew: "878067389634314250";
- awkword: "879863881349087252";
- spellcast: "852509694341283871";
-}
+import { CathError } from "../Error/CathError";
+import axios from "axios";
+/**
+ * Start a Discord Activity session
+ * @example
+ * const Cath = require("cath")
+ * const client = new Client()
+ * const d = await Cath.DiscordActivity({
+ application: "youtube",
+ channel_id: "901542111005012099",
+ token: client.token,
+ });
+ message.channel.send({ content: d });
+ */
+export async function DiscordActivity(options: DiscordActivityOptions) {
+ const all = {
+ youtube: "880218394199220334",
+ youtubedev: "880218832743055411",
+ poker: "755827207812677713",
+ betrayal: "773336526917861400",
+ fishing: "814288819477020702",
+ chess: "832012774040141894",
+ chessdev: "832012586023256104",
+ lettertile: "879863686565621790",
+ wordsnack: "879863976006127627",
+ doodlecrew: "878067389634314250",
+ awkword: "879863881349087252",
+ spellcast: "852509694341283871",
+ };
+ if (!all[options.application]) {
+ throw new CathError(
+ "Application ID is not valid, if you want to see the list of applications, check the docs at https://cath.js.org/interfaces/Applications.html"
+ );
+ }
+ if (!options.token) {
+ throw new CathError("Missing 'token'");
+ }
+ if (!options.channel_id) {
+ throw new CathError("Missing 'Channel ID'");
+ }
+ const data = await axios
+ .post(
+ `https://discord.com/api/v9/channels/${options.channel_id}/invites`,
+ {
+ max_age: 86400,
+ max_uses: 0,
+ target_application_id: all[options.application],
+ target_type: 2,
+ temporary: false,
+ validate: null,
+ },
+ {
+ headers: {
+ Authorization: `Bot ${options.token}`,
+ "Content-Type": "application/json",
+ },
+ }
+ )
+ .then(res => res.data);
+ return `https://discord.com/invite/${data.code}`;
+}
+export interface DiscordActivityOptions {
+ application: string;
+ token: string;
+ channel_id: string;
+}
+export interface Applications {
+ youtube: "880218394199220334";
+ youtubedev: "880218832743055411";
+ poker: "755827207812677713";
+ betrayal: "773336526917861400";
+ fishing: "814288819477020702";
+ chess: "832012774040141894";
+ chessdev: "832012586023256104";
+ lettertile: "879863686565621790";
+ wordsnack: "879863976006127627";
+ doodlecrew: "878067389634314250";
+ awkword: "879863881349087252";
+ spellcast: "852509694341283871";
+}
diff --git a/src/functions/doublestruck.ts b/src/functions/doublestruck.ts
index 0be2951..3c53fb2 100644
--- a/src/functions/doublestruck.ts
+++ b/src/functions/doublestruck.ts
@@ -1,16 +1,16 @@
-import axios from "axios";
-import { CathError } from "../Error/CathError";
-import { config } from "../";
-/**
- * Dobulestruck words
- */
-export async function doublestruck(word: string): Promise {
- if (!word) {
- throw new CathError("Missing 'word'");
- }
- const data = await axios
- .get(`${config.api}/api/v1/fun/doublestruck?text=${word}`)
- .then(res => res.data);
- console.log(data);
- return data.text;
-}
+import axios from "axios";
+import { CathError } from "../Error/CathError";
+import { config } from "../";
+/**
+ * Dobulestruck words
+ */
+export async function doublestruck(word: string): Promise {
+ if (!word) {
+ throw new CathError("Missing 'word'");
+ }
+ const data = await axios
+ .get(`${config.api}/api/v1/fun/doublestruck?text=${word}`)
+ .then(res => res.data);
+ console.log(data);
+ return data.text;
+}
diff --git a/src/functions/emojify.ts b/src/functions/emojify.ts
index 165afcb..a3eb701 100644
--- a/src/functions/emojify.ts
+++ b/src/functions/emojify.ts
@@ -1,34 +1,34 @@
-/**
- * Emoji-ify a string
- */
-export function emojify(str: string): string {
- const s = {
- 0: ":zero:",
- 1: ":one:",
- 2: ":two:",
- 3: ":three:",
- 4: ":four:",
- 5: ":five:",
- 6: ":six:",
- 7: ":seven:",
- 8: ":eight:",
- 9: ":nine:",
- "#": ":hash:",
- "*": ":asterisk:",
- "!": ":grey_exclamation:",
- "?": ":grey_question:",
- " ": " ",
- };
- let ar = str
- .toLowerCase()
- .split("")
- .map(l => {
- if (/[a-z]/g.test(l)) {
- return `:regional_indicator_${l}:`;
- } else if (s[l]) {
- return `${s[l]}`;
- }
- })
- .join("");
- return ar;
-}
+/**
+ * Emoji-ify a string
+ */
+export function emojify(str: string): string {
+ const s = {
+ 0: ":zero:",
+ 1: ":one:",
+ 2: ":two:",
+ 3: ":three:",
+ 4: ":four:",
+ 5: ":five:",
+ 6: ":six:",
+ 7: ":seven:",
+ 8: ":eight:",
+ 9: ":nine:",
+ "#": ":hash:",
+ "*": ":asterisk:",
+ "!": ":grey_exclamation:",
+ "?": ":grey_question:",
+ " ": " ",
+ };
+ let ar = str
+ .toLowerCase()
+ .split("")
+ .map(l => {
+ if (/[a-z]/g.test(l)) {
+ return `:regional_indicator_${l}:`;
+ } else if (s[l]) {
+ return `${s[l]}`;
+ }
+ })
+ .join("");
+ return ar;
+}
diff --git a/src/functions/formatUpper.ts b/src/functions/formatUpper.ts
index 65d7753..d4e5fc7 100644
--- a/src/functions/formatUpper.ts
+++ b/src/functions/formatUpper.ts
@@ -1,9 +1,9 @@
-import { CathError } from "../Error/CathError";
-
-/**
- * Edit the first letter of the string to uppercase
- */
-export function formatUpper(str: string) {
- if (!str) throw new CathError("Missing 'str'");
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
-}
+import { CathError } from "../Error/CathError";
+
+/**
+ * Edit the first letter of the string to uppercase
+ */
+export function formatUpper(str: string) {
+ if (!str) throw new CathError("Missing 'str'");
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
+}
diff --git a/src/functions/fractur.ts b/src/functions/fractur.ts
index b29dd60..f6ddc5c 100644
--- a/src/functions/fractur.ts
+++ b/src/functions/fractur.ts
@@ -1,16 +1,16 @@
-import axios from "axios";
-import { CathError } from "../Error/CathError";
-import { config } from "../";
-/**
- * Sends a 8ball response
- */
-export async function fractur(word: string): Promise {
- if (!word) {
- throw new CathError("Missing 'word'");
- }
- const data = await axios
- .get(`${config.api}/api/v1/fun/fractur?text=${word}`)
- .then(res => res.data);
- console.log(data);
- return data.text;
-}
+import axios from "axios";
+import { CathError } from "../Error/CathError";
+import { config } from "../";
+/**
+ * Sends a 8ball response
+ */
+export async function fractur(word: string): Promise {
+ if (!word) {
+ throw new CathError("Missing 'word'");
+ }
+ const data = await axios
+ .get(`${config.api}/api/v1/fun/fractur?text=${word}`)
+ .then(res => res.data);
+ console.log(data);
+ return data.text;
+}
diff --git a/src/functions/generatePassword.ts b/src/functions/generatePassword.ts
index 787b2fe..59d541b 100644
--- a/src/functions/generatePassword.ts
+++ b/src/functions/generatePassword.ts
@@ -1,35 +1,35 @@
-/**
- * Generate a random password
- * @param length The length of the password
- * @param options The options for the password
- */
-export function generatePassword(
- length: number,
- options: GeneratePasswordOptions
-) {
- const upper = options.upper || false;
- const lower = options.lower || false;
- const numbers = options.numbers || false;
- const special = options.special || false;
- const upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- const lowerChars = "abcdefghijklmnopqrstuvwxyz";
- const numberChars = "0123456789";
- const specialChars = "!@#$%^&*()_+-=[]{}|;':\",./<>?";
- let password = "";
- let chars = "";
- if (upper) chars += upperChars;
- if (lower) chars += lowerChars;
- if (numbers) chars += numberChars;
- if (special) chars += specialChars;
- for (let i = 0; i < length; i++) {
- password += chars.charAt(Math.floor(Math.random() * chars.length));
- }
- return password;
-}
-
-export interface GeneratePasswordOptions {
- upper: boolean;
- lower: boolean;
- numbers: boolean;
- special: boolean;
-}
+/**
+ * Generate a random password
+ * @param length The length of the password
+ * @param options The options for the password
+ */
+export function generatePassword(
+ length: number,
+ options: GeneratePasswordOptions
+) {
+ const upper = options.upper || false;
+ const lower = options.lower || false;
+ const numbers = options.numbers || false;
+ const special = options.special || false;
+ const upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ const lowerChars = "abcdefghijklmnopqrstuvwxyz";
+ const numberChars = "0123456789";
+ const specialChars = "!@#$%^&*()_+-=[]{}|;':\",./<>?";
+ let password = "";
+ let chars = "";
+ if (upper) chars += upperChars;
+ if (lower) chars += lowerChars;
+ if (numbers) chars += numberChars;
+ if (special) chars += specialChars;
+ for (let i = 0; i < length; i++) {
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
+ }
+ return password;
+}
+
+export interface GeneratePasswordOptions {
+ upper: boolean;
+ lower: boolean;
+ numbers: boolean;
+ special: boolean;
+}
diff --git a/src/functions/getLilaseDownloads.ts b/src/functions/getLilaseDownloads.ts
index f99d7f8..718878e 100644
--- a/src/functions/getLilaseDownloads.ts
+++ b/src/functions/getLilaseDownloads.ts
@@ -1,15 +1,15 @@
-const axios = require("axios");
-/**
- * @name getLilaseDownloads
- * @description Get the number of downloads
- */
-export async function getLilaseDownloads(): Promise {
- const { data } = await axios.get(
- "https://api.github.com/repos/night0721/Lilase/releases"
- );
- let sum = 0;
- data.forEach(release => {
- sum += release.assets[0].download_count;
- });
- return sum;
-}
+const axios = require("axios");
+/**
+ * @name getLilaseDownloads
+ * @description Get the number of downloads
+ */
+export async function getLilaseDownloads(): Promise {
+ const { data } = await axios.get(
+ "https://api.github.com/repos/night0721/Lilase/releases"
+ );
+ let sum = 0;
+ data.forEach(release => {
+ sum += release.assets[0].download_count;
+ });
+ return sum;
+}
diff --git a/src/functions/ms.ts b/src/functions/ms.ts
index 18ed059..2b25d29 100644
--- a/src/functions/ms.ts
+++ b/src/functions/ms.ts
@@ -1,138 +1,138 @@
-import { CathError } from "../Error/CathError";
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var mn = d * 30;
-var w = d * 7;
-var y = d * 365.25;
-export function parseString(val: string) {
- var type = typeof val;
- if (type === "string" && val.length > 0) {
- return parse(val);
- }
- throw new CathError("Missing 'val' or type of 'val' isn't a string");
-}
-export function parseMS(val: number, options?: msOptions) {
- options = options || {};
- if (isFinite(val)) {
- return options?.long ? fmtLong(val) : fmtShort(val);
- }
- throw new CathError("Missing 'val' or type of 'val' isn't a number");
-}
-function parse(str) {
- str = String(str);
- if (str.length > 100) {
- return;
- }
- var match =
- /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mths|mn|years?|yrs?|y)?$/i.exec(
- str
- );
- if (!match) {
- return;
- }
- var n = parseFloat(match[1]);
- var type = (match[2] || "ms").toLowerCase();
- switch (type) {
- case "years":
- case "year":
- case "yrs":
- case "yr":
- case "y":
- return n * y;
- case "month":
- case "months":
- case "mth":
- case "mths":
- return n * mn;
- case "weeks":
- case "week":
- case "w":
- return n * w;
- case "days":
- case "day":
- case "d":
- return n * d;
- case "hours":
- case "hour":
- case "hrs":
- case "hr":
- case "h":
- return n * h;
- case "minutes":
- case "minute":
- case "mins":
- case "min":
- case "m":
- return n * m;
- case "seconds":
- case "second":
- case "secs":
- case "sec":
- case "s":
- return n * s;
- case "milliseconds":
- case "millisecond":
- case "msecs":
- case "msec":
- case "ms":
- return n;
- default:
- return undefined;
- }
-}
-
-function fmtShort(ms: number): string {
- var msAbs = Math.abs(ms);
- if (msAbs >= mn) {
- return Math.round(ms / mn) + "mo";
- }
- if (msAbs >= w) {
- return Math.round(ms / w) + "w";
- }
- if (msAbs >= d) {
- return Math.round(ms / d) + "d";
- }
- if (msAbs >= h) {
- return Math.round(ms / h) + "h";
- }
- if (msAbs >= m) {
- return Math.round(ms / m) + "m";
- }
- if (msAbs >= s) {
- return Math.round(ms / s) + "s";
- }
- return ms + "ms";
-}
-
-function fmtLong(ms: number) {
- var msAbs = Math.abs(ms);
- if (msAbs >= mn) {
- return plural(ms, msAbs, mn, "month");
- }
- if (msAbs >= w) {
- return plural(ms, msAbs, w, "week");
- }
- if (msAbs >= d) {
- return plural(ms, msAbs, d, "day");
- }
- if (msAbs >= h) {
- return plural(ms, msAbs, h, "hour");
- }
- if (msAbs >= m) {
- return plural(ms, msAbs, m, "minute");
- }
- if (msAbs >= s) {
- return plural(ms, msAbs, s, "second");
- }
- return ms + " ms";
-}
-function plural(ms: number, msAbs: number, n: number, name: string) {
- var isPlural = msAbs >= n * 1.5;
- return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
-}
-export interface msOptions {
- long?: boolean;
- short?: boolean;
-}
+import { CathError } from "../Error/CathError";
+var s = 1000;
+var m = s * 60;
+var h = m * 60;
+var d = h * 24;
+var mn = d * 30;
+var w = d * 7;
+var y = d * 365.25;
+export function parseString(val: string) {
+ var type = typeof val;
+ if (type === "string" && val.length > 0) {
+ return parse(val);
+ }
+ throw new CathError("Missing 'val' or type of 'val' isn't a string");
+}
+export function parseMS(val: number, options?: msOptions) {
+ options = options || {};
+ if (isFinite(val)) {
+ return options?.long ? fmtLong(val) : fmtShort(val);
+ }
+ throw new CathError("Missing 'val' or type of 'val' isn't a number");
+}
+function parse(str) {
+ str = String(str);
+ if (str.length > 100) {
+ return;
+ }
+ var match =
+ /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mths|mn|years?|yrs?|y)?$/i.exec(
+ str
+ );
+ if (!match) {
+ return;
+ }
+ var n = parseFloat(match[1]);
+ var type = (match[2] || "ms").toLowerCase();
+ switch (type) {
+ case "years":
+ case "year":
+ case "yrs":
+ case "yr":
+ case "y":
+ return n * y;
+ case "month":
+ case "months":
+ case "mth":
+ case "mths":
+ return n * mn;
+ case "weeks":
+ case "week":
+ case "w":
+ return n * w;
+ case "days":
+ case "day":
+ case "d":
+ return n * d;
+ case "hours":
+ case "hour":
+ case "hrs":
+ case "hr":
+ case "h":
+ return n * h;
+ case "minutes":
+ case "minute":
+ case "mins":
+ case "min":
+ case "m":
+ return n * m;
+ case "seconds":
+ case "second":
+ case "secs":
+ case "sec":
+ case "s":
+ return n * s;
+ case "milliseconds":
+ case "millisecond":
+ case "msecs":
+ case "msec":
+ case "ms":
+ return n;
+ default:
+ return undefined;
+ }
+}
+
+function fmtShort(ms: number): string {
+ var msAbs = Math.abs(ms);
+ if (msAbs >= mn) {
+ return Math.round(ms / mn) + "mo";
+ }
+ if (msAbs >= w) {
+ return Math.round(ms / w) + "w";
+ }
+ if (msAbs >= d) {
+ return Math.round(ms / d) + "d";
+ }
+ if (msAbs >= h) {
+ return Math.round(ms / h) + "h";
+ }
+ if (msAbs >= m) {
+ return Math.round(ms / m) + "m";
+ }
+ if (msAbs >= s) {
+ return Math.round(ms / s) + "s";
+ }
+ return ms + "ms";
+}
+
+function fmtLong(ms: number) {
+ var msAbs = Math.abs(ms);
+ if (msAbs >= mn) {
+ return plural(ms, msAbs, mn, "month");
+ }
+ if (msAbs >= w) {
+ return plural(ms, msAbs, w, "week");
+ }
+ if (msAbs >= d) {
+ return plural(ms, msAbs, d, "day");
+ }
+ if (msAbs >= h) {
+ return plural(ms, msAbs, h, "hour");
+ }
+ if (msAbs >= m) {
+ return plural(ms, msAbs, m, "minute");
+ }
+ if (msAbs >= s) {
+ return plural(ms, msAbs, s, "second");
+ }
+ return ms + " ms";
+}
+function plural(ms: number, msAbs: number, n: number, name: string) {
+ var isPlural = msAbs >= n * 1.5;
+ return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
+}
+export interface msOptions {
+ long?: boolean;
+ short?: boolean;
+}
diff --git a/src/functions/obama.ts b/src/functions/obama.ts
index 2ca9234..36abca3 100644
--- a/src/functions/obama.ts
+++ b/src/functions/obama.ts
@@ -1,42 +1,42 @@
-/**
- * Obama!
- */
-export function obama() {
- const o = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠛⠛⠉⠉⠉⠋⠛⠛⠛⠻⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const b = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠛⠉⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠉⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const a = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const m = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠏⠄⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠹⣿⣿⣿⣿⣿⣿⣿";
- const a2 = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠘⢻⣿⣿⣿⣿⣿";
- const aa = "⣿⣿⣿⣿⣿⣿⣿⣿⠃⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⢀⠄⢠⠄⠄⡀⠄⠄⢀⠂⠄⠄⠄⠄⠄⠄⠄⠄⠄⡁⠄⠄⢛⣿⣿⣿⣿";
- const ab = "⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⡈⢔⠸⣐⢕⢕⢵⢰⢱⢰⢐⢤⡡⡢⣕⢄⢢⢠⠄⠄⠄⠄⠄⠄⠙⣿⣿⣿";
- const ac = "⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡁⠂⠅⢕⠌⡎⡎⣎⢎⢮⢮⣳⡳⣝⢮⢺⢜⢕⢕⢍⢎⠪⡐⠄⠁⠄⠸⣿⣿";
- const ad = "⣿⣿⣿⣿⣿⣿⠏⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⠄⠄⢅⠣⡡⡣⣣⡳⡵⣝⡮⣗⣗⡯⣗⣟⡮⡮⣳⣣⣳⢱⢱⠱⣐⠄⠂⠄⢿⣿";
- const ae = "⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⢂⢈⠢⡱⡱⡝⣮⣿⣟⣿⣽⣷⣿⣯⣿⣷⣿⣿⣿⣾⣯⣗⡕⡇⡇⠄⠂⡀⢹⣿";
- const af = "⣿⣿⣿⣿⣿⡟⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⠐⢀⢂⢕⢸⢨⢪⢳⡫⣟⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡺⡮⡣⡣⠠⢂⠒⢸⣿";
- const ag = "⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠐⠄⡂⠆⡇⣗⣝⢮⢾⣻⣞⣿⣿⣿⣿⣿⣿⣿⣿⢿⣽⣯⡯⣺⢸⢘⠨⠔⡅⢨⣿";
- const ah = "⣿⣿⠋⠉⠙⠃⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠁⠄⠄⠄⡂⡪⡪⡪⡮⡮⡯⣻⣽⣾⣿⣿⣿⣟⣿⣿⣿⣽⣿⣿⡯⣯⡺⡸⡰⡱⢐⡅⣼⣿";
- const ai = "⣿⠡⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠈⠆⠱⠑⠝⠜⠕⡝⡝⣞⢯⢿⣿⣿⡿⣟⣿⣿⣿⡿⡿⣽⣷⣽⡸⡨⡪⣂⠊⣿⣿";
- const aj = "⣿⠡⠄⡨⣢⠐⠁⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⠍⡓⣗⡽⣝⠽⠍⠅⠑⠁⠉⠘⠘⠘⠵⡑⢜⢀⢀⢉⢽";
- const ak = "⣿⠁⠠⢱⢘⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠈⠱⣁⠜⡘⠌⠄⠄⡪⣳⣟⡮⢅⠤⠠⠄⠄⣀⣀⡀⡀⠄⠈⡂⢲⡪⡠⣿";
- const al = "⣿⡇⠨⣺⢐⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡀⠄⠄⠄⠤⡠⡢⢒⠦⠠⠄⠄⠄⡸⢽⣟⢮⠢⡂⡐⠄⡈⡀⠤⡀⠄⠑⢄⠨⢸⡺⣐⣿";
- const am = "⣿⣿⠈⠕⠁⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡂⡪⡐⡥⢤⣰⣰⣰⡴⡮⠢⠂⠄⠄⡊⢮⢺⢕⢵⢥⡬⣌⣒⡚⣔⢚⢌⢨⢚⠌⣾⡪⣾⣿";
- const an = "⣿⣿⣆⠄⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡑⢕⢕⡯⡷⣕⢧⢓⢭⠨⡀⠄⡂⠨⡨⣪⡳⣝⢝⡽⣻⣻⣞⢽⣲⢳⢱⢡⠱⠨⣟⢺⣿⣿";
- const ao = "⣿⣿⣿⡆⠄⡅⠇⡄⠄⠄⠄⠄⠄⠄⠄⠐⠨⢪⢹⢽⢽⣺⢝⠉⠁⠁⠄⠄⠄⢌⢎⡖⡯⡎⡗⢝⠜⣶⣯⣻⢮⡻⣟⣳⡕⠅⣷⣿⣿⣿";
- const ap = "⣿⣿⣿⣿⣶⣶⣿⣷⠄⠄⠄⠄⠄⠄⠄⠄⠈⠔⡑⠕⠝⠄⡀⠄⠄⠊⢆⠂⠨⡪⣺⣮⣿⡾⡜⣜⡜⣄⠙⢞⣿⢿⡿⣗⢝⢸⣾⣿⣿⣿";
- const aq = "⣿⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⡀⠄⠄⠄⠄⢀⠄⠠⠄⠠⠄⠄⠄⠄⠄⠄⠊⠺⡹⠳⡙⡜⡓⡭⡺⡀⠄⠣⡻⡹⡸⠨⣣⣿⣿⣿⣿";
- const ar = "⣿⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠠⠄⠄⣂⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⢄⠤⡤⡄⡆⡯⡢⡣⡣⡓⢕⠽⣄⠄⠨⡂⢌⣼⣿⣿⣿⣿⣿";
- const a_ = "⣿⣿⣿⣿⣿⣿⣿⣿⡆⠄⠄⠄⠄⠈⠆⠄⠸⡂⠄⠄⠄⢀⠄⢀⠈⠄⠂⠁⠙⠝⠼⠭⠣⠣⠣⠑⠌⠢⠣⡣⡠⡘⣰⣱⣿⣿⣿⣿⣿⣿";
- const at = "⣿⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⢑⠄⠈⡱⠄⢘⠄⡀⠨⢐⣧⣳⣷⣶⣦⣤⣴⣶⣶⣶⡶⠄⡠⡢⡕⣜⠎⡮⣣⣿⣿⣿⣿⣿⣿⣿";
- const au = "⣿⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠢⠄⠨⠄⠄⠣⡀⠄⢀⢀⢙⠃⡿⢿⠿⡿⡿⢟⢋⢔⡱⣝⢜⡜⡪⡪⣵⣿⣿⣿⣿⣿⣿⣿⣿";
- const av = "⣿⣿⣿⣿⣿⣿⣿⣿⡁⠄⠄⠄⠄⠄⠄⠄⠅⠄⠡⠄⠄⠡⢀⢂⠢⡡⠡⠣⡑⣏⢯⡻⡳⣹⡺⡪⢎⠎⡆⢣⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const aw = "⣿⣿⣿⣿⣿⣿⣿⣿⣇⠄⠄⠄⠄⠄⠄⠄⠐⠄⠄⠁⠄⢈⠄⢂⠕⡕⡝⢕⢎⢎⢮⢎⢯⢺⢸⢬⠣⢃⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const ax = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠨⡐⠌⢆⢇⢧⢭⣣⡳⣵⢫⣳⢱⠱⢑⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const ay = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣆⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠁⡊⢌⢢⢡⢣⢪⡺⡪⡎⡎⡎⡚⣨⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const az = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠕⡅⢗⢕⡳⡭⣳⢕⠕⡱⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const ba = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠌⠄⠑⠩⢈⢂⣱⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const bb = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⡀⢄⠄⣀⠄⡀⣀⢠⢄⣖⣖⣞⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- const bc = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣱⡐⡕⡕⡽⣝⣟⣮⣾⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
- console.log(
- `${o}\n${b}\n${a}\n${m}\n${a2}\n${aa}\n${ab}\n${ac}\n${ad}\n${ae}\n${af}\n${ag}\n${ah}\n${ai}\n${aj}\n${ak}\n${al}\n${am}\n${an}\n${ao}\n${ap}\n${aq}\n${ar}\n${a_}\n${at}\n${au}\n${av}\n${aw}\n${ax}\n${ay}\n${az}\n${ba}\n${bb}\n${bc}`
- );
-}
+/**
+ * Obama!
+ */
+export function obama() {
+ const o = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠛⠛⠛⠉⠉⠉⠋⠛⠛⠛⠻⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const b = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠛⠉⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠉⠙⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const a = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠋⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const m = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠏⠄⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠹⣿⣿⣿⣿⣿⣿⣿";
+ const a2 = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⠛⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠘⢻⣿⣿⣿⣿⣿";
+ const aa = "⣿⣿⣿⣿⣿⣿⣿⣿⠃⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⢀⠄⢠⠄⠄⡀⠄⠄⢀⠂⠄⠄⠄⠄⠄⠄⠄⠄⠄⡁⠄⠄⢛⣿⣿⣿⣿";
+ const ab = "⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⡈⢔⠸⣐⢕⢕⢵⢰⢱⢰⢐⢤⡡⡢⣕⢄⢢⢠⠄⠄⠄⠄⠄⠄⠙⣿⣿⣿";
+ const ac = "⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡁⠂⠅⢕⠌⡎⡎⣎⢎⢮⢮⣳⡳⣝⢮⢺⢜⢕⢕⢍⢎⠪⡐⠄⠁⠄⠸⣿⣿";
+ const ad = "⣿⣿⣿⣿⣿⣿⠏⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⠄⠄⢅⠣⡡⡣⣣⡳⡵⣝⡮⣗⣗⡯⣗⣟⡮⡮⣳⣣⣳⢱⢱⠱⣐⠄⠂⠄⢿⣿";
+ const ae = "⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⢂⢈⠢⡱⡱⡝⣮⣿⣟⣿⣽⣷⣿⣯⣿⣷⣿⣿⣿⣾⣯⣗⡕⡇⡇⠄⠂⡀⢹⣿";
+ const af = "⣿⣿⣿⣿⣿⡟⠄⠄⠄⠄⠄⠄⠂⠄⠄⠄⠄⠄⠄⠐⢀⢂⢕⢸⢨⢪⢳⡫⣟⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡺⡮⡣⡣⠠⢂⠒⢸⣿";
+ const ag = "⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠐⠄⡂⠆⡇⣗⣝⢮⢾⣻⣞⣿⣿⣿⣿⣿⣿⣿⣿⢿⣽⣯⡯⣺⢸⢘⠨⠔⡅⢨⣿";
+ const ah = "⣿⣿⠋⠉⠙⠃⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠁⠄⠄⠄⡂⡪⡪⡪⡮⡮⡯⣻⣽⣾⣿⣿⣿⣟⣿⣿⣿⣽⣿⣿⡯⣯⡺⡸⡰⡱⢐⡅⣼⣿";
+ const ai = "⣿⠡⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠈⠆⠱⠑⠝⠜⠕⡝⡝⣞⢯⢿⣿⣿⡿⣟⣿⣿⣿⡿⡿⣽⣷⣽⡸⡨⡪⣂⠊⣿⣿";
+ const aj = "⣿⠡⠄⡨⣢⠐⠁⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠐⠍⡓⣗⡽⣝⠽⠍⠅⠑⠁⠉⠘⠘⠘⠵⡑⢜⢀⢀⢉⢽";
+ const ak = "⣿⠁⠠⢱⢘⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠈⠈⠱⣁⠜⡘⠌⠄⠄⡪⣳⣟⡮⢅⠤⠠⠄⠄⣀⣀⡀⡀⠄⠈⡂⢲⡪⡠⣿";
+ const al = "⣿⡇⠨⣺⢐⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡀⠄⠄⠄⠤⡠⡢⢒⠦⠠⠄⠄⠄⡸⢽⣟⢮⠢⡂⡐⠄⡈⡀⠤⡀⠄⠑⢄⠨⢸⡺⣐⣿";
+ const am = "⣿⣿⠈⠕⠁⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡂⡪⡐⡥⢤⣰⣰⣰⡴⡮⠢⠂⠄⠄⡊⢮⢺⢕⢵⢥⡬⣌⣒⡚⣔⢚⢌⢨⢚⠌⣾⡪⣾⣿";
+ const an = "⣿⣿⣆⠄⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⡑⢕⢕⡯⡷⣕⢧⢓⢭⠨⡀⠄⡂⠨⡨⣪⡳⣝⢝⡽⣻⣻⣞⢽⣲⢳⢱⢡⠱⠨⣟⢺⣿⣿";
+ const ao = "⣿⣿⣿⡆⠄⡅⠇⡄⠄⠄⠄⠄⠄⠄⠄⠐⠨⢪⢹⢽⢽⣺⢝⠉⠁⠁⠄⠄⠄⢌⢎⡖⡯⡎⡗⢝⠜⣶⣯⣻⢮⡻⣟⣳⡕⠅⣷⣿⣿⣿";
+ const ap = "⣿⣿⣿⣿⣶⣶⣿⣷⠄⠄⠄⠄⠄⠄⠄⠄⠈⠔⡑⠕⠝⠄⡀⠄⠄⠊⢆⠂⠨⡪⣺⣮⣿⡾⡜⣜⡜⣄⠙⢞⣿⢿⡿⣗⢝⢸⣾⣿⣿⣿";
+ const aq = "⣿⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⡀⠄⠄⠄⠄⢀⠄⠠⠄⠠⠄⠄⠄⠄⠄⠄⠊⠺⡹⠳⡙⡜⡓⡭⡺⡀⠄⠣⡻⡹⡸⠨⣣⣿⣿⣿⣿";
+ const ar = "⣿⣿⣿⣿⣿⣿⣿⣿⠄⠄⠄⠄⠄⠠⠄⠄⣂⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⢄⠤⡤⡄⡆⡯⡢⡣⡣⡓⢕⠽⣄⠄⠨⡂⢌⣼⣿⣿⣿⣿⣿";
+ const a_ = "⣿⣿⣿⣿⣿⣿⣿⣿⡆⠄⠄⠄⠄⠈⠆⠄⠸⡂⠄⠄⠄⢀⠄⢀⠈⠄⠂⠁⠙⠝⠼⠭⠣⠣⠣⠑⠌⠢⠣⡣⡠⡘⣰⣱⣿⣿⣿⣿⣿⣿";
+ const at = "⣿⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⢑⠄⠈⡱⠄⢘⠄⡀⠨⢐⣧⣳⣷⣶⣦⣤⣴⣶⣶⣶⡶⠄⡠⡢⡕⣜⠎⡮⣣⣿⣿⣿⣿⣿⣿⣿";
+ const au = "⣿⣿⣿⣿⣿⣿⣿⣿⡇⠄⠄⠄⠄⠄⠄⠢⠄⠨⠄⠄⠣⡀⠄⢀⢀⢙⠃⡿⢿⠿⡿⡿⢟⢋⢔⡱⣝⢜⡜⡪⡪⣵⣿⣿⣿⣿⣿⣿⣿⣿";
+ const av = "⣿⣿⣿⣿⣿⣿⣿⣿⡁⠄⠄⠄⠄⠄⠄⠄⠅⠄⠡⠄⠄⠡⢀⢂⠢⡡⠡⠣⡑⣏⢯⡻⡳⣹⡺⡪⢎⠎⡆⢣⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const aw = "⣿⣿⣿⣿⣿⣿⣿⣿⣇⠄⠄⠄⠄⠄⠄⠄⠐⠄⠄⠁⠄⢈⠄⢂⠕⡕⡝⢕⢎⢎⢮⢎⢯⢺⢸⢬⠣⢃⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const ax = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠠⠨⡐⠌⢆⢇⢧⢭⣣⡳⣵⢫⣳⢱⠱⢑⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const ay = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣆⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠁⡊⢌⢢⢡⢣⢪⡺⡪⡎⡎⡎⡚⣨⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const az = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠕⡅⢗⢕⡳⡭⣳⢕⠕⡱⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const ba = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠄⠄⠄⠄⠄⠄⠄⠄⠄⠌⠄⠑⠩⢈⢂⣱⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const bb = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⡀⢄⠄⣀⠄⡀⣀⢠⢄⣖⣖⣞⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ const bc = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣱⡐⡕⡕⡽⣝⣟⣮⣾⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿";
+ console.log(
+ `${o}\n${b}\n${a}\n${m}\n${a2}\n${aa}\n${ab}\n${ac}\n${ad}\n${ae}\n${af}\n${ag}\n${ah}\n${ai}\n${aj}\n${ak}\n${al}\n${am}\n${an}\n${ao}\n${ap}\n${aq}\n${ar}\n${a_}\n${at}\n${au}\n${av}\n${aw}\n${ax}\n${ay}\n${az}\n${ba}\n${bb}\n${bc}`
+ );
+}
diff --git a/src/functions/pagination.ts b/src/functions/pagination.ts
index 971bc5a..1f0878a 100644
--- a/src/functions/pagination.ts
+++ b/src/functions/pagination.ts
@@ -1,52 +1,52 @@
-import { Message, MessageEmbed, User } from "discord.js";
-export class Pagination {
- constructor() {}
- public chunk(arr, size: number) {
- const temp = [];
- for (let i = 0; i < arr.length; i += size) {
- temp.push(arr.slice(i, i + size));
- }
- return temp;
- }
-
- paginationEmojis = ["◀", "⛔", "▶"];
-
- public async pagination(
- msg: Message,
- author: User,
- contents: MessageEmbed,
- init = true,
- currPage = 0
- ) {
- if (init) for (const emoji of this.paginationEmojis) await msg.react(emoji);
- const filter = (reaction, user) => {
- return (
- this.paginationEmojis.includes(reaction.emoji.name) &&
- user.id === author.id
- );
- };
- const collector = msg.createReactionCollector({
- filter,
- max: 1,
- time: 90000,
- });
- collector
- .on("collect", reaction => {
- reaction.users.remove(author);
- const emoji = reaction.emoji.name;
- if (emoji === this.paginationEmojis[0]) currPage--;
- if (emoji === this.paginationEmojis[1]) return collector.stop();
- if (emoji === this.paginationEmojis[2]) currPage++;
- currPage =
- ((currPage % contents.length) + contents.length) % contents.length;
- const embed = msg.embeds[0]
- .setDescription(contents[currPage])
- .setFooter(`Page ${currPage + 1} of ${contents.length}`);
- msg.edit({ embeds: [embed] });
- this.pagination(msg, author, contents, false, currPage);
- })
- .on("end", (_, reason) => {
- if (["time", "user"].includes(reason)) msg.reactions.removeAll();
- });
- }
-}
+import { Message, MessageEmbed, User } from "discord.js";
+export class Pagination {
+ constructor() {}
+ public chunk(arr, size: number) {
+ const temp = [];
+ for (let i = 0; i < arr.length; i += size) {
+ temp.push(arr.slice(i, i + size));
+ }
+ return temp;
+ }
+
+ paginationEmojis = ["◀", "⛔", "▶"];
+
+ public async pagination(
+ msg: Message,
+ author: User,
+ contents: MessageEmbed,
+ init = true,
+ currPage = 0
+ ) {
+ if (init) for (const emoji of this.paginationEmojis) await msg.react(emoji);
+ const filter = (reaction, user) => {
+ return (
+ this.paginationEmojis.includes(reaction.emoji.name) &&
+ user.id === author.id
+ );
+ };
+ const collector = msg.createReactionCollector({
+ filter,
+ max: 1,
+ time: 90000,
+ });
+ collector
+ .on("collect", reaction => {
+ reaction.users.remove(author);
+ const emoji = reaction.emoji.name;
+ if (emoji === this.paginationEmojis[0]) currPage--;
+ if (emoji === this.paginationEmojis[1]) return collector.stop();
+ if (emoji === this.paginationEmojis[2]) currPage++;
+ currPage =
+ ((currPage % contents.length) + contents.length) % contents.length;
+ const embed = msg.embeds[0]
+ .setDescription(contents[currPage])
+ .setFooter(`Page ${currPage + 1} of ${contents.length}`);
+ msg.edit({ embeds: [embed] });
+ this.pagination(msg, author, contents, false, currPage);
+ })
+ .on("end", (_, reason) => {
+ if (["time", "user"].includes(reason)) msg.reactions.removeAll();
+ });
+ }
+}
diff --git a/src/functions/randint.ts b/src/functions/randint.ts
index 1742b0a..b241679 100644
--- a/src/functions/randint.ts
+++ b/src/functions/randint.ts
@@ -1,8 +1,8 @@
-import { CathError } from "../Error/CathError";
-/**
- * Returns a random number in range
- */
-export function randint(max: number, min: number) {
- if (!max || !min) throw new CathError("Missing number");
- return Math.floor(Math.random() * (max - (min ? min : 0))) + (min ? min : 0);
-}
+import { CathError } from "../Error/CathError";
+/**
+ * Returns a random number in range
+ */
+export function randint(max: number, min: number) {
+ if (!max || !min) throw new CathError("Missing number");
+ return Math.floor(Math.random() * (max - (min ? min : 0))) + (min ? min : 0);
+}
diff --git a/src/functions/randomID.ts b/src/functions/randomID.ts
index 339a861..7d72cb0 100644
--- a/src/functions/randomID.ts
+++ b/src/functions/randomID.ts
@@ -1,13 +1,13 @@
-import { CathError } from "../Error/CathError";
-/**
- * Returns a random ID/String
- */
-export function randomID(length: number) {
- if (!length) throw new CathError("Missing 'length'");
- var result = "";
- var c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- for (var i = 0; i < length; i++) {
- result += c.charAt(Math.floor(Math.random() * c.length));
- }
- return result;
-}
+import { CathError } from "../Error/CathError";
+/**
+ * Returns a random ID/String
+ */
+export function randomID(length: number) {
+ if (!length) throw new CathError("Missing 'length'");
+ var result = "";
+ var c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ for (var i = 0; i < length; i++) {
+ result += c.charAt(Math.floor(Math.random() * c.length));
+ }
+ return result;
+}
diff --git a/src/functions/reddit.ts b/src/functions/reddit.ts
index a9f3521..acb44dc 100644
--- a/src/functions/reddit.ts
+++ b/src/functions/reddit.ts
@@ -1,31 +1,31 @@
-import axios from "axios";
-import { CathError } from "../Error/CathError";
-/**
- * Sends an embed of reddit
- */
-export async function getreddit(sub: string): Promise {
- if (!sub) throw new CathError("Missing Subreddit");
- const content = await axios
- .get(`https://www.reddit.com/r/${sub}/random/.json`)
- .then(res => res.data);
- let permalink = content[0].data.children[0].data.permalink;
- let memeURL = `https://reddit.com${permalink}`;
- let memeImage = content[0].data.children[0].data.url;
- let memeTitle = content[0].data.children[0].data.title;
- let memeUpvotes = content[0].data.children[0].data.ups;
- let memeDownvotes = content[0].data.children[0].data.downs;
- let memeNumComments = content[0].data.children[0].data.num_comments;
- const obj: RedditObject = {
- title: memeTitle,
- url: memeURL,
- image: memeImage,
- footer: ` 👍 ${memeUpvotes} 💬 ${memeNumComments}`,
- };
- return obj;
-}
-export interface RedditObject {
- title: String;
- url: String;
- image: String;
- footer: String;
-}
+import axios from "axios";
+import { CathError } from "../Error/CathError";
+/**
+ * Sends an embed of reddit
+ */
+export async function getreddit(sub: string): Promise {
+ if (!sub) throw new CathError("Missing Subreddit");
+ const content = await axios
+ .get(`https://www.reddit.com/r/${sub}/random/.json`)
+ .then(res => res.data);
+ let permalink = content[0].data.children[0].data.permalink;
+ let memeURL = `https://reddit.com${permalink}`;
+ let memeImage = content[0].data.children[0].data.url;
+ let memeTitle = content[0].data.children[0].data.title;
+ let memeUpvotes = content[0].data.children[0].data.ups;
+ let memeDownvotes = content[0].data.children[0].data.downs;
+ let memeNumComments = content[0].data.children[0].data.num_comments;
+ const obj: RedditObject = {
+ title: memeTitle,
+ url: memeURL,
+ image: memeImage,
+ footer: ` 👍 ${memeUpvotes} 💬 ${memeNumComments}`,
+ };
+ return obj;
+}
+export interface RedditObject {
+ title: String;
+ url: String;
+ image: String;
+ footer: String;
+}
diff --git a/src/functions/round.ts b/src/functions/round.ts
index ff655e3..19153f0 100644
--- a/src/functions/round.ts
+++ b/src/functions/round.ts
@@ -1,6 +1,6 @@
-/**
- * Rounds a number to a specified number of decimal places.
- */
-export function round(value: number, decimals: number) {
- return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
-}
+/**
+ * Rounds a number to a specified number of decimal places.
+ */
+export function round(value: number, decimals: number) {
+ return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
+}
diff --git a/src/functions/selectRandom.ts b/src/functions/selectRandom.ts
index b802a7d..d09922c 100644
--- a/src/functions/selectRandom.ts
+++ b/src/functions/selectRandom.ts
@@ -1,9 +1,9 @@
-import { CathError } from "../Error/CathError";
-/**
- * Select a random element of the array
- */
-export function selectRandom(array = []): any {
- if (!array) throw new CathError("Missing 'array'");
- if (!array.length) throw new CathError("array length can't be 0");
- return array[Math.floor(Math.random() * array.length)];
-}
+import { CathError } from "../Error/CathError";
+/**
+ * Select a random element of the array
+ */
+export function selectRandom(array = []): any {
+ if (!array) throw new CathError("Missing 'array'");
+ if (!array.length) throw new CathError("array length can't be 0");
+ return array[Math.floor(Math.random() * array.length)];
+}
diff --git a/src/functions/sleep.ts b/src/functions/sleep.ts
index 49e1002..78db268 100644
--- a/src/functions/sleep.ts
+++ b/src/functions/sleep.ts
@@ -1,9 +1,9 @@
-import { CathError } from "../Error/CathError";
-export function sleep(ms: number) {
- if (!ms) throw new CathError("Missing 'ms'");
- let start = new Date().getTime();
- let end = start;
- while (end < start + ms) {
- end = new Date().getTime();
- }
-}
+import { CathError } from "../Error/CathError";
+export function sleep(ms: number) {
+ if (!ms) throw new CathError("Missing 'ms'");
+ let start = new Date().getTime();
+ let end = start;
+ while (end < start + ms) {
+ end = new Date().getTime();
+ }
+}
diff --git a/src/functions/superscript.ts b/src/functions/superscript.ts
index 16f11aa..80b898e 100644
--- a/src/functions/superscript.ts
+++ b/src/functions/superscript.ts
@@ -1,16 +1,16 @@
-import axios from "axios";
-import { CathError } from "../Error/CathError";
-import { config } from "../";
-/**
- * Sends a superscript-ed word
- */
-export async function superscript(word: string): Promise {
- if (!word) {
- throw new CathError("Missing 'word'");
- }
- const data = await axios
- .get(`${config.api}/api/v1/fun/superscript?text=${word}`)
- .then(res => res.data);
- console.log(data);
- return data.text;
-}
+import axios from "axios";
+import { CathError } from "../Error/CathError";
+import { config } from "../";
+/**
+ * Sends a superscript-ed word
+ */
+export async function superscript(word: string): Promise {
+ if (!word) {
+ throw new CathError("Missing 'word'");
+ }
+ const data = await axios
+ .get(`${config.api}/api/v1/fun/superscript?text=${word}`)
+ .then(res => res.data);
+ console.log(data);
+ return data.text;
+}
diff --git a/src/functions/timer.ts b/src/functions/timer.ts
index 6877b87..c0a343c 100644
--- a/src/functions/timer.ts
+++ b/src/functions/timer.ts
@@ -1,20 +1,20 @@
-import { CathError } from "../Error/CathError";
-export function timer(timestamp: number) {
- if (!timestamp) throw new CathError("Missing 'timestamp");
- const timeLeft = timestamp;
- const days = Math.floor(timeLeft / 86400000);
- const hours = Math.floor(timeLeft / 3600000) - days * 24;
- const minutes = Math.floor(timeLeft / 60000) - days * 1440 - hours * 60;
- const seconds =
- Math.floor(timeLeft / 1000) - days * 86400 - hours * 3600 - minutes * 60;
- const mseconds = timeLeft / 1000 - days * 86400 - hours * 3600 - minutes * 60;
- let string = "";
- if (days) string = string + `${days} ${days == 1 ? "day " : "days "}`;
- if (hours) string = string + `${hours} ${hours == 1 ? "hour " : "hours "}`;
- if (minutes)
- string = string + `${minutes} ${minutes == 1 ? "minute " : "minutes "}`;
- if (seconds)
- string = string + `${seconds} ${seconds == 1 ? "second " : "seconds "}`;
- if (!string.length) string = `${mseconds.toFixed(1)} second`;
- return string;
-}
+import { CathError } from "../Error/CathError";
+export function timer(timestamp: number) {
+ if (!timestamp) throw new CathError("Missing 'timestamp");
+ const timeLeft = timestamp;
+ const days = Math.floor(timeLeft / 86400000);
+ const hours = Math.floor(timeLeft / 3600000) - days * 24;
+ const minutes = Math.floor(timeLeft / 60000) - days * 1440 - hours * 60;
+ const seconds =
+ Math.floor(timeLeft / 1000) - days * 86400 - hours * 3600 - minutes * 60;
+ const mseconds = timeLeft / 1000 - days * 86400 - hours * 3600 - minutes * 60;
+ let string = "";
+ if (days) string = string + `${days} ${days == 1 ? "day " : "days "}`;
+ if (hours) string = string + `${hours} ${hours == 1 ? "hour " : "hours "}`;
+ if (minutes)
+ string = string + `${minutes} ${minutes == 1 ? "minute " : "minutes "}`;
+ if (seconds)
+ string = string + `${seconds} ${seconds == 1 ? "second " : "seconds "}`;
+ if (!string.length) string = `${mseconds.toFixed(1)} second`;
+ return string;
+}
diff --git a/src/functions/trimArray.ts b/src/functions/trimArray.ts
index f6392b6..0ea5a42 100644
--- a/src/functions/trimArray.ts
+++ b/src/functions/trimArray.ts
@@ -1,14 +1,14 @@
-import { CathError } from "../Error/CathError";
-
-/**
- * Trim an array from 10th elemnt
- */
-export function trimArray(arr = []) {
- if (!arr) throw new CathError("Missing 'arr'");
- if (arr.length > 10) {
- const length = arr.length - 10;
- arr = arr.slice(0, 10);
- arr.push(`\n${length} more...`);
- }
- return arr.join(" **|** ");
-}
+import { CathError } from "../Error/CathError";
+
+/**
+ * Trim an array from 10th elemnt
+ */
+export function trimArray(arr = []) {
+ if (!arr) throw new CathError("Missing 'arr'");
+ if (arr.length > 10) {
+ const length = arr.length - 10;
+ arr = arr.slice(0, 10);
+ arr.push(`\n${length} more...`);
+ }
+ return arr.join(" **|** ");
+}
diff --git a/src/index.d.ts b/src/index.d.ts
index ff4f55f..f841612 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,49 +1,49 @@
-export { CODMClient, CODMClientOptions, PerkData } from "./CODMClient";
-export {
- StarboardClient,
- StarboardClientOptions,
- StarboardGuild,
- StarboardGuildOptions,
- starMessageData,
-} from "./StarboardClient";
-export { CodeClient, CodeData } from "./CodeClient";
-export { URLClient, URLData } from "./URLClient";
-export {
- GiveawaysClient,
- GiveawaySchema,
- GiveawaysClientOptions,
- DefaultGiveawayMessages,
-} from "./GiveawaysClient";
-export { ImageClient } from "./ImageClient/index";
-export { random8ball } from "./functions/8ball";
-export { getreddit, RedditObject } from "./functions/reddit";
-export { Pagination } from "./functions/pagination";
-export { bool } from "./functions/bool";
-export { randint } from "./functions/randint";
-export { timer } from "./functions/timer";
-export { selectRandom } from "./functions/selectRandom";
-export { parseMS, parseString } from "./functions/ms";
-export { confirmation } from "./functions/confirmation";
-export { HHMMSS } from "./functions/HHMMSS";
-export { formatUpper } from "./functions/formatUpper";
-export { cleanText } from "./functions/cleanText";
-export { daysAgo } from "./functions/daysAgo";
-export { sleep } from "./functions/sleep";
-export { trimArray } from "./functions/trimArray";
-export { randomID } from "./functions/randomID";
-export {
- DiscordActivity,
- DiscordActivityOptions,
- Applications,
-} from "./functions/discord-activity";
-export { superscript } from "./functions/superscript";
-export { doublestruck } from "./functions/doublestruck";
-export { fractur } from "./functions/fractur";
-export { round } from "./functions/round";
-export {
- generatePassword,
- GeneratePasswordOptions,
-} from "./functions/generatePassword";
-export { getLilaseDownloads } from "./functions/getLilaseDownloads";
-export { emojify } from "./functions/emojify";
-export { obama } from "./functions/obama";
+export { CODMClient, CODMClientOptions, PerkData } from "./CODMClient";
+export {
+ StarboardClient,
+ StarboardClientOptions,
+ StarboardGuild,
+ StarboardGuildOptions,
+ starMessageData,
+} from "./StarboardClient";
+export { CodeClient, CodeData } from "./CodeClient";
+export { URLClient, URLData } from "./URLClient";
+export {
+ GiveawaysClient,
+ GiveawaySchema,
+ GiveawaysClientOptions,
+ DefaultGiveawayMessages,
+} from "./GiveawaysClient";
+export { ImageClient } from "./ImageClient/index";
+export { random8ball } from "./functions/8ball";
+export { getreddit, RedditObject } from "./functions/reddit";
+export { Pagination } from "./functions/pagination";
+export { bool } from "./functions/bool";
+export { randint } from "./functions/randint";
+export { timer } from "./functions/timer";
+export { selectRandom } from "./functions/selectRandom";
+export { parseMS, parseString } from "./functions/ms";
+export { confirmation } from "./functions/confirmation";
+export { HHMMSS } from "./functions/HHMMSS";
+export { formatUpper } from "./functions/formatUpper";
+export { cleanText } from "./functions/cleanText";
+export { daysAgo } from "./functions/daysAgo";
+export { sleep } from "./functions/sleep";
+export { trimArray } from "./functions/trimArray";
+export { randomID } from "./functions/randomID";
+export {
+ DiscordActivity,
+ DiscordActivityOptions,
+ Applications,
+} from "./functions/discord-activity";
+export { superscript } from "./functions/superscript";
+export { doublestruck } from "./functions/doublestruck";
+export { fractur } from "./functions/fractur";
+export { round } from "./functions/round";
+export {
+ generatePassword,
+ GeneratePasswordOptions,
+} from "./functions/generatePassword";
+export { getLilaseDownloads } from "./functions/getLilaseDownloads";
+export { emojify } from "./functions/emojify";
+export { obama } from "./functions/obama";
diff --git a/src/index.ts b/src/index.ts
index fd3b8ff..86eb049 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,55 +1,55 @@
-export {
- CODMClient,
- CODMClientOptions,
- PerkData,
- ScorestreakData,
-} from "./CODMClient";
-export {
- StarboardClient,
- StarboardClientOptions,
- StarboardGuild,
- StarboardGuildOptions,
- starMessageData,
-} from "./StarboardClient";
-export { CodeClient, CodeData } from "./CodeClient";
-export { URLClient, URLData } from "./URLClient";
-export {
- GiveawaysClient,
- GiveawaySchema,
- GiveawaysClientOptions,
- DefaultGiveawayMessages,
-} from "./GiveawaysClient";
-export { ImageClient } from "./ImageClient/index";
-export { random8ball } from "./functions/8ball";
-export { getreddit, RedditObject } from "./functions/reddit";
-export { Pagination } from "./functions/pagination";
-export { bool } from "./functions/bool";
-export { randint } from "./functions/randint";
-export { timer } from "./functions/timer";
-export { selectRandom } from "./functions/selectRandom";
-export { parseMS, parseString } from "./functions/ms";
-export { confirmation } from "./functions/confirmation";
-export { HHMMSS } from "./functions/HHMMSS";
-export { formatUpper } from "./functions/formatUpper";
-export {
- DiscordActivity,
- DiscordActivityOptions,
- Applications,
-} from "./functions/discord-activity";
-export { cleanText } from "./functions/cleanText";
-export { daysAgo } from "./functions/daysAgo";
-export { sleep } from "./functions/sleep";
-export { trimArray } from "./functions/trimArray";
-export { superscript } from "./functions/superscript";
-export { doublestruck } from "./functions/doublestruck";
-export { fractur } from "./functions/fractur";
-export { randomID } from "./functions/randomID";
-export { round } from "./functions/round";
-export {
- generatePassword,
- GeneratePasswordOptions,
-} from "./functions/generatePassword";
-export { getLilaseDownloads } from "./functions/getLilaseDownloads";
-export { emojify } from "./functions/emojify";
-export { obama } from "./functions/obama";
-export { ConfigURLS, config } from "./config";
+export {
+ CODMClient,
+ CODMClientOptions,
+ PerkData,
+ ScorestreakData,
+} from "./CODMClient";
+export {
+ StarboardClient,
+ StarboardClientOptions,
+ StarboardGuild,
+ StarboardGuildOptions,
+ starMessageData,
+} from "./StarboardClient";
+export { CodeClient, CodeData } from "./CodeClient";
+export { URLClient, URLData } from "./URLClient";
+export {
+ GiveawaysClient,
+ GiveawaySchema,
+ GiveawaysClientOptions,
+ DefaultGiveawayMessages,
+} from "./GiveawaysClient";
+export { ImageClient } from "./ImageClient/index";
+export { random8ball } from "./functions/8ball";
+export { getreddit, RedditObject } from "./functions/reddit";
+export { Pagination } from "./functions/pagination";
+export { bool } from "./functions/bool";
+export { randint } from "./functions/randint";
+export { timer } from "./functions/timer";
+export { selectRandom } from "./functions/selectRandom";
+export { parseMS, parseString } from "./functions/ms";
+export { confirmation } from "./functions/confirmation";
+export { HHMMSS } from "./functions/HHMMSS";
+export { formatUpper } from "./functions/formatUpper";
+export {
+ DiscordActivity,
+ DiscordActivityOptions,
+ Applications,
+} from "./functions/discord-activity";
+export { cleanText } from "./functions/cleanText";
+export { daysAgo } from "./functions/daysAgo";
+export { sleep } from "./functions/sleep";
+export { trimArray } from "./functions/trimArray";
+export { superscript } from "./functions/superscript";
+export { doublestruck } from "./functions/doublestruck";
+export { fractur } from "./functions/fractur";
+export { randomID } from "./functions/randomID";
+export { round } from "./functions/round";
+export {
+ generatePassword,
+ GeneratePasswordOptions,
+} from "./functions/generatePassword";
+export { getLilaseDownloads } from "./functions/getLilaseDownloads";
+export { emojify } from "./functions/emojify";
+export { obama } from "./functions/obama";
+export { ConfigURLS, config } from "./config";
diff --git a/tsconfig.json b/tsconfig.json
index 5e26e82..0708e72 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,20 +1,20 @@
-{
- "compilerOptions": {
- "lib": ["ESNext"],
- "module": "commonjs",
- "moduleResolution": "node",
- "target": "ESNext",
- "declaration": true,
- "outDir": "dist",
- "sourceMap": false,
- "esModuleInterop": true,
- "experimentalDecorators": true,
- "emitDecoratorMetadata": true,
- "allowSyntheticDefaultImports": true,
- "skipLibCheck": true,
- "skipDefaultLibCheck": true,
- "resolveJsonModule": true
- },
- "include": ["./src"],
- "exclude": ["./node_modules"]
-}
+{
+ "compilerOptions": {
+ "lib": ["ESNext"],
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "target": "ESNext",
+ "declaration": true,
+ "outDir": "dist",
+ "sourceMap": false,
+ "esModuleInterop": true,
+ "experimentalDecorators": true,
+ "emitDecoratorMetadata": true,
+ "allowSyntheticDefaultImports": true,
+ "skipLibCheck": true,
+ "skipDefaultLibCheck": true,
+ "resolveJsonModule": true
+ },
+ "include": ["./src"],
+ "exclude": ["./node_modules"]
+}
diff --git a/vercel.json b/vercel.json
index 540ffc6..a3eec4c 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,7 +1,7 @@
-{
- "git": {
- "deploymentEnabled": {
- "main": false
- }
- }
-}
+{
+ "git": {
+ "deploymentEnabled": {
+ "main": false
+ }
+ }
+}