├── .github
└── workflows
│ └── deploy.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── composer.json
├── config
└── spell-number.php
├── docs
├── .vitepress
│ └── config.mts
├── contribute
│ ├── contribution.md
│ └── report-bugs.md
├── getting-started
│ ├── changelog.md
│ ├── installation.md
│ ├── introduction.md
│ └── publish-vendor.md
├── index.md
├── public
│ ├── css
│ │ └── style.css
│ └── img
│ │ ├── favicon.svg
│ │ ├── laravel-red.svg
│ │ ├── laravel_black.svg
│ │ ├── logo-full-scream.png
│ │ ├── logo-github.png
│ │ └── logo.png
└── usage
│ ├── config-custom-callback.md
│ ├── config-file.md
│ ├── languages-available.md
│ ├── macroable.md
│ ├── numbers-to-letters.md
│ ├── numbers-to-money.md
│ └── numbers-to-ordinal.md
├── package-lock.json
├── package.json
├── src
├── Bases
│ ├── BaseSpellNumber.php
│ └── BaseSpellNumberValidator.php
├── Callback
│ └── DataResponse.php
├── Exceptions
│ └── SpellNumberExceptions.php
├── Langs
│ ├── Langs.php
│ └── Replaces.php
├── Miscellaneous
│ ├── Utilities.php
│ └── Words.php
├── Providers
│ └── SpellNumberProvider.php
├── SpellNumber.php
├── Traits
│ ├── Accesor.php
│ └── Locale.php
├── Validator
│ ├── SpellNumberValidator.php
│ └── Traits
│ │ └── CommonValidate.php
└── Wrappers
│ └── NumberFormatterWrapper.php
└── test
└── SpellNumberTest.php
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy VitePress site to Pages
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 |
7 | # Allows you to run this workflow manually from the Actions tab
8 | workflow_dispatch:
9 |
10 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
11 | permissions:
12 | contents: read
13 | pages: write
14 | id-token: write
15 |
16 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
17 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
18 | concurrency:
19 | group: pages
20 | cancel-in-progress: false
21 |
22 | jobs:
23 | # Build job
24 | build:
25 | runs-on: ubuntu-latest
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v3
29 | with:
30 | fetch-depth: 0 # Not needed if lastUpdated is not enabled
31 | # - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm
32 | # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
33 | - name: Setup Node
34 | uses: actions/setup-node@v3
35 | with:
36 | node-version: 18
37 | cache: npm # or pnpm / yarn
38 | - name: Setup Pages
39 | uses: actions/configure-pages@v3
40 | - name: Install dependencies
41 | run: npm ci # or pnpm install / yarn install / bun install
42 | - name: Build with VitePress
43 | run: |
44 | npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
45 | touch docs/.vitepress/dist/.nojekyll
46 | - name: Upload artifact
47 | uses: actions/upload-pages-artifact@v2
48 | with:
49 | path: docs/.vitepress/dist
50 |
51 | # Deployment job
52 | deploy:
53 | environment:
54 | name: github-pages
55 | url: ${{ steps.deployment.outputs.page_url }}
56 | needs: build
57 | runs-on: ubuntu-latest
58 | name: Deploy
59 | steps:
60 | - name: Deploy to GitHub Pages
61 | id: deployment
62 | uses: actions/deploy-pages@v2
63 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore common macOS files and directories
2 | **/.DS_Store
3 |
4 | # Ignore automatically generated files and directories
5 | /vendor/
6 | /.fleet
7 | /.idea
8 | /.vscode
9 |
10 | # Ignore Composer generated directory and files
11 | /vendor
12 |
13 | # Ignore development tool generated files and directories
14 | .fleet
15 | .idea
16 | .vscode
17 | composer.lock
18 |
19 | #Node
20 | node_modules
21 | docs/.vitepress/cache
22 | docs/.vitepress/dist
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Raúl Mauricio Uñate Castro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Convert Numbers to Words in Laravel
2 |
3 | [](https://laravel.com/docs/11.x/helpers#method-number-spell)
4 |
5 | **This project has been discontinued.**
6 |
7 | Now, this functionality is part of the **Core of Laravel Framework**. Check out the usage of the `Illuminate\Support\Number` class in the [official Laravel documentation](https://laravel.com/docs/11.x/helpers#method-number-spell).
8 |
9 | ### Details:
10 | - **Version:** 10.41
11 | - **Pull Request:** [PR #48845](https://github.com/laravel/framework/pull/48845)
12 |
13 | ---
14 | ---
15 | ---
16 | ---
17 |
18 | ## Introduction
19 |
20 | Easily convert numbers to words in Laravel using this library, which leverages the native `PHP INTL` extension to perform conversion effortlessly. With this library, you can convert numbers to words in various languages and also obtain the value in currency format according to the selected language. Supported languages include English, Spanish, Portuguese, French, Italian, Romanian, Hindi, Polish, Vietnamese and Persian (Farsi).
21 |
22 | **This library is compatible with PHP +8.0 and Laravel versions 8.0 and higher**
23 |
24 | 
25 |
26 | ## Requirements
27 |
28 | For this solution to work properly you must have at least a version of PHP 8.0 since the package in its CORE has typed data.
29 |
30 | You must have Laravel Framework version 8 or higher.
31 |
32 | Finally, our package relies on the native PHP `INTL` extension, check in your `php.ini` that you have it.
33 |
34 | ## Install
35 |
36 | ### Composer
37 |
38 | To install the dependency via Composer, execute the following command:
39 |
40 | ``` bash
41 | composer require rmunate/spell-number
42 | ```
43 |
44 | The package will automatically register itself.
45 |
46 | **That's all!**
47 |
48 | ## Usage
49 |
50 | [](https://rmunate.github.io/SpellNumber/)
51 |
52 | # Contributing
53 |
54 | If you want to add support for a new language or want to develop new features, you can submit your requests to the main branch of the repository.
55 |
56 | To date, the following world-class developers have contributed their knowledge.
57 |
58 | To whom we thank for supporting making programming easier.
59 |
60 | - [Ashok Devatwal](https://github.com/ashokdevatwal) (Hindi Language)
61 | - [Olsza](https://github.com/olsza) (Polish Language)
62 | - [Siros Fakhri](https://github.com/sirosfakhri) (Farsi Language)
63 | - [Jens Twesmann](https://github.com/jetwes) (German Language)
64 | - [Gabriel Rausch](https://github.com/gdsrmygdsrjr) (Zero Decimal Correction)
65 | - [Alejandro Diaz](https://github.com/alejandrodiazpinilla) (Readme And Icon)
66 | - [Frank Sepulveda](https://github.com/socieboy) (Ordinal Texts)
67 | - [Ngô Quốc Đạt](https://github.com/datlechin) (Vietnamese Language)
68 |
69 | ## License
70 | This project is under the [MIT License](https://choosealicense.com/licenses/mit/).
71 |
72 | 🌟 Support My Projects! 🚀
73 |
74 | [](https://github.com/sponsors/rmunate)
75 |
76 | Make any contributions you see fit; the code is entirely yours. Together, we can do amazing things and improve the world of development. Your support is invaluable. ✨
77 |
78 | If you have ideas, suggestions, or just want to collaborate, we are open to everything! Join our community and be part of our journey to success! 🌐👩💻👨💻
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rmunate/spell-number",
3 | "description": "Easily convert numbers to letters, this library supports the native PHP INTL extension with which we can easily convert numbers to letters. This library provides us with the possibility of converting only to numbers or to currency formats depending on the language to be used, this package has support in the languages en: English, es: Spanish, pt: Portuguese, fr: French, it: Italian, ro: Romanian, fa: Farsi, hi: Hindi, pl: Polish.",
4 | "keywords": [
5 | "towords",
6 | "toletters",
7 | "numbers",
8 | "spell",
9 | "spell-number",
10 | "spell-numbers",
11 | "code-maestro",
12 | "rmunate"
13 | ],
14 | "homepage": "https://github.com/rmunate/SpellNumber",
15 | "type": "library",
16 | "license": "MIT",
17 | "autoload": {
18 | "psr-4": {
19 | "Rmunate\\Utilities\\": "src/"
20 | }
21 | },
22 | "authors": [
23 | {
24 | "name": "Raul Mauricio Uñate Castro",
25 | "email": "raulmauriciounate@gmail.com",
26 | "homepage": "https://github.com/rmunate",
27 | "role": "owner"
28 | },
29 | {
30 | "name": "Olsza",
31 | "homepage": "https://github.com/olsza",
32 | "role": "developer"
33 | },
34 | {
35 | "name": "Er. Ashok Devatwal",
36 | "email": "ashokdev78@gmail.com",
37 | "homepage": "https://github.com/ashokdevatwal",
38 | "role": "developer"
39 | },
40 | {
41 | "name": "Siros Fakhri",
42 | "homepage": "https://github.com/sirosfakhri",
43 | "role": "developer"
44 | },
45 | {
46 | "name": "Jens Twesmann",
47 | "homepage": "https://github.com/jetwes",
48 | "role": "developer"
49 | },
50 | {
51 | "name": "Gabriel Rausch",
52 | "homepage": "https://github.com/gdsrmygdsrjr",
53 | "role": "developer"
54 | },
55 | {
56 | "name": "Alejandro Diaz",
57 | "homepage": "https://github.com/alejandrodiazpinilla",
58 | "role": "developer"
59 | }
60 | ],
61 | "require": {
62 | "php": "^8.0",
63 | "ext-intl": "*",
64 | "illuminate/support": "^8.0|^9.0|^10.0"
65 | },
66 | "require-dev": {
67 | "phpunit/phpunit": "^10.4"
68 | },
69 | "extra" : {
70 | "branch-alias" : {
71 | "dev-main": "1.0.x-dev"
72 | },
73 | "laravel": {
74 | "providers": [
75 | "Rmunate\\Utilities\\Providers\\SpellNumberProvider"
76 | ]
77 | }
78 | },
79 | "minimum-stability": "dev",
80 | "prefer-stable": true
81 | }
82 |
--------------------------------------------------------------------------------
/config/spell-number.php:
--------------------------------------------------------------------------------
1 | [
16 |
17 | /*
18 | |--------------------------------------------------------------------------
19 | | Default Locale for Number to Words Translation.
20 | |--------------------------------------------------------------------------
21 | |
22 | | Define the language over which values will be translated to words.
23 | | Remember that you only have the following options available:
24 | | 'de', 'en', 'es', 'fa', 'fr', 'hi', 'it', 'pl', 'pt', 'ro'.
25 | |
26 | */
27 |
28 | 'locale' => 'en',
29 |
30 | /*
31 | |--------------------------------------------------------------------------
32 | | Try using a "locale" not listed in the previous option.
33 | |--------------------------------------------------------------------------
34 | |
35 | | If you want to use an option different from those previously listed,
36 | | you must set the following indicator to true, so that the conversion to the supplied
37 | | location can be attempted. To list possible additional options to use with the package,
38 | | you can run the function SpellNumber::getAllLocales();
39 | |
40 | */
41 |
42 | 'specific_locale' => false,
43 |
44 | /*
45 | |--------------------------------------------------------------------------
46 | | Define the Currency.
47 | |--------------------------------------------------------------------------
48 | |
49 | | Define the name of the currency to use globally.
50 | | This will reduce the amount of code when using the library.
51 | |
52 | */
53 |
54 | 'currency' => 'dollars',
55 |
56 | /*
57 | |--------------------------------------------------------------------------
58 | | Define the Fraction.
59 | |--------------------------------------------------------------------------
60 | |
61 | | Define the name of the currency fraction to use globally.
62 | | This will reduce the amount of code when using the library.
63 | | Cents? What will you use?.
64 | |
65 | */
66 |
67 | 'fraction' => 'cents',
68 |
69 | /*
70 | |--------------------------------------------------------------------------
71 | | Output type ordinal texts
72 | |--------------------------------------------------------------------------
73 | |
74 | | The output usually depends on the language to be used,
75 | | so you can use any of the following three options.
76 | |
77 | | Options: 'default', 'male', 'female'
78 | |
79 | */
80 |
81 | 'ordinal_output' => 'default',
82 | ],
83 |
84 | /*
85 | |--------------------------------------------------------------------------
86 | | Sometimes you need to replace certain things in the number to words outputs.
87 | |--------------------------------------------------------------------------
88 | |
89 | | If so, it's very easy to do.
90 | | Use the structure of an associative array to apply these replacements to your outputs.
91 | |
92 | */
93 |
94 | 'replacements' => [
95 | // 'en' => [
96 | // 'that' => 'this',
97 | // ],
98 | ],
99 |
100 | /*
101 | |--------------------------------------------------------------------------
102 | | Encountered a specific adjustment in the number to words output?.
103 | |--------------------------------------------------------------------------
104 | |
105 | | Here, you have the option to adjust whatever you need, the best part!
106 | | This adjustment will apply to all your number to words outputs.
107 | |
108 | */
109 |
110 | 'callback_output' => function ($data) {
111 | // Your logic here...
112 |
113 | return $data->getWords();
114 | },
115 | ];
116 |
--------------------------------------------------------------------------------
/docs/.vitepress/config.mts:
--------------------------------------------------------------------------------
1 | import {defineConfig} from 'vitepress'
2 |
3 | export default defineConfig({
4 | title: "Laravel SpellNumber",
5 | description: "Easily convert numbers to words in Laravel Framework.",
6 | lang: 'en-US',
7 | lastUpdated: false,
8 | base: '/SpellNumber',
9 | themeConfig: {
10 | footer: {
11 | message: 'Released under the MIT License.',
12 | copyright: 'Copyright © 2021-2023 Raul Mauricio Uñate'
13 | },
14 | editLink: {
15 | pattern: 'https://github.com/rmunate/SpellNumber/tree/main/docs/:path'
16 | },
17 | logo: '/img/logo.png',
18 | nav: [
19 | {text: 'v4.2.2', link: '/'},
20 | ],
21 | sidebar: [
22 | {
23 | text: 'Getting Started',
24 | collapsed: false,
25 | items: [
26 | {text: 'Introduction', link: '/getting-started/introduction'},
27 | {text: 'Installation', link: '/getting-started/installation'},
28 | {text: 'Publish Vendor', link: '/getting-started/publish-vendor'},
29 | {text: 'Release Notes', link: '/getting-started/changelog'},
30 | ]
31 | }, {
32 | text: 'Usage',
33 | collapsed: false,
34 | items: [
35 | {text: 'Languages Available', link: '/usage/languages-available.md'},
36 | {text: 'Numbers To Letters', link: '/usage/numbers-to-letters'},
37 | {text: 'Numbers To Money', link: '/usage/numbers-to-money'},
38 | {text: 'Numbers To Ordinal', link: '/usage/numbers-to-ordinal'},
39 | {text: 'Config File', link: '/usage/config-file'},
40 | {text: 'Config Custom Callback', link: '/usage/config-custom-callback'},
41 | {text: 'Macroable', link: '/usage/macroable'},
42 | ]
43 | }, {
44 | text: 'Contribute',
45 | collapsed: false,
46 | items: [
47 | {text: 'Bug Report', link: 'contribute/report-bugs'},
48 | {text: 'Contribution', link: 'contribute/contribution'}
49 | ]
50 | }
51 | ],
52 |
53 | socialLinks: [
54 | {icon: 'github', link: 'https://github.com/rmunate/SpellNumber'}
55 | ],
56 | search: {
57 | provider: 'local'
58 | }
59 | },
60 | head: [
61 | ['link', {
62 | rel: 'stylesheet',
63 | href: '/SpellNumber/css/style.css'
64 | }
65 | ],
66 | ['link', {
67 | rel: 'icon',
68 | href: '/SpellNumber/img/logo.png',
69 | type: 'image/png'
70 | }
71 | ],
72 | ['meta', {
73 | property: 'og:image',
74 | content: '/SpellNumber/img/logo-github.png'
75 | }
76 | ],
77 | ['meta', {
78 | property: 'og:image:secure_url',
79 | content: '/SpellNumber/img/logo-github.png'
80 | }
81 | ],
82 | ['meta', {
83 | property: 'og:image:width',
84 | content: '600'
85 | }
86 | ],
87 | ['meta', {
88 | property: 'og:image:height',
89 | content: '400'
90 | }
91 | ],
92 | ['meta', {
93 | property: 'og:title',
94 | content: 'SpellNumber'
95 | }
96 | ],
97 | ['meta', {
98 | property: 'og:description',
99 | content: 'Effortlessly Convert Numbers to Words in Laravel! 🚀'
100 | }
101 | ],
102 | ['meta', {
103 | property: 'og:url',
104 | content: 'https://rmunate.github.io/SpellNumber/'
105 | }
106 | ],
107 | ['meta', {
108 | property: 'og:type',
109 | content: 'website'
110 | }
111 | ],
112 | ],
113 | })
114 |
--------------------------------------------------------------------------------
/docs/contribute/contribution.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Contributing
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 |
81 |
82 | # Contributing
83 |
84 | If you want to add support for a new language or want to develop new features, you can submit your requests to the main branch of the repository.
85 |
86 | ## Contributors
87 |
88 | To date, the following world-class developers have contributed their knowledge.
89 |
90 | To whom we thank for supporting making programming easier.
91 |
92 |
93 |
94 | ## License
95 | This project is under the [MIT License](https://choosealicense.com/licenses/mit/).
96 |
97 | 🌟 Support My Projects! 🚀
98 |
99 | [](https://github.com/sponsors/rmunate)
100 |
101 | Make any contributions you see fit; the code is entirely yours. Together, we can do amazing things and improve the world of development. Your support is invaluable. ✨
102 |
103 | If you have ideas, suggestions, or just want to collaborate, we are open to everything! Join our community and be part of our journey to success! 🌐👩💻👨💻
--------------------------------------------------------------------------------
/docs/contribute/report-bugs.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Bug Report
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Bug Report
8 |
9 | If you find errors or opportunities within the package, you can create an incident that we will attend to in the shortest time possible.
10 |
11 | Here!:
12 | [https://github.com/rmunate/SpellNumber/issues/new](https://github.com/rmunate/SpellNumber/issues/new)
13 |
14 | Remember that you can also contribute as a collaborator of this solution.
15 |
--------------------------------------------------------------------------------
/docs/getting-started/changelog.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Release Notes
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Release Notes
8 |
9 | ## [4.2.0] - 2023-11-20
10 |
11 | ### Added
12 |
13 | - **Vietnamese Language Support**: Introduced connectors and replacements for the Vietnamese language.
14 |
15 | ### Changed
16 |
17 | - **TitleCase to LowerCase**: In response to specific language nuances, output is now in lowercase. Developers have the option to modify the output as needed, keeping in mind the use of the callback function.
18 |
19 | To swiftly revert to title-formatted output, simply publish the configuration file:
20 |
21 | ```bash
22 | php artisan vendor:publish --provider="Rmunate\\Utilities\\Providers\\SpellNumberProvider" --tag="config"
23 | ```
24 |
25 | Then, locate the callback function and adjust the return statement in the configuration file:
26 |
27 | ```php
28 | return [
29 | //...
30 | 'callback_output' => function ($data) {
31 |
32 | // Your logic here...
33 |
34 | return \Illuminate\Support\Str::title($data->getWords());
35 | },
36 | ]
37 | ```
38 |
39 | ## [4.2.2] - 2023-11-28
40 |
41 | ### Changed
42 |
43 | - **Zero-width spaces:** Characters (\u{AD}, \u{200B}) are removed from the translation outputs.
--------------------------------------------------------------------------------
/docs/getting-started/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Installation
8 |
9 | ## Requirements
10 |
11 | For this solution to work correctly, you must have at least PHP 8.0 installed, as the package includes typed data in its core.
12 |
13 | You must have Laravel Framework version 8 or higher.
14 |
15 | Finally, our package relies on the native PHP `INTL` extension, check in your `php.ini` that you have it.
16 |
17 | ## Install
18 |
19 | ### Composer
20 |
21 | To install the dependency via Composer, execute the following command:
22 |
23 | ``` bash
24 | composer require rmunate/spell-number
25 | ```
26 |
27 | The package will automatically register itself.
28 |
29 | **That's all!**
30 |
--------------------------------------------------------------------------------
/docs/getting-started/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | 
8 |
9 | ## Introduction
10 |
11 | Easily convert numbers to words in Laravel using this library, which leverages the native `PHP INTL` extension to perform conversion effortlessly. With this library, you can convert numbers to words in various languages and also obtain the value in currency format according to the selected language.
12 |
13 | Supported languages include English, Spanish, Portuguese, French, Italian, Romanian, Hindi, Polish and Persian (Farsi).
14 |
15 | **This library is compatible with PHP +8.0 and Laravel versions 8.0 and higher**
16 |
--------------------------------------------------------------------------------
/docs/getting-started/publish-vendor.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration File
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Laravel Configuration File
8 |
9 | This is optional.
10 |
11 | You can publish the config-file with:
12 |
13 | ``` bash
14 | php artisan vendor:publish --provider="Rmunate\\Utilities\\Providers\\SpellNumberProvider" --tag="config"
15 | ```
16 |
17 | [View File on GitHub](https://github.com/rmunate/SpellNumber/blob/1cca5565d6b8c049683357bcbb964b70bcfc4a92/config/spell-number.php)
18 |
19 | The configuration file will prove valuable if you intend to consistently use a single target language for converting numbers into letters.
20 |
21 | It also provides a comprehensive global output manipulation feature, empowering you to implement various adjustments or restore settings to the default package letter output.
22 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 |
4 | hero:
5 | name: Laravel
6 | text: Spell Number
7 | tagline: Effortlessly Convert Numbers to Words in Laravel! 🚀
8 | image:
9 | src: /img/logo.png
10 | alt: SpellNumber
11 | actions:
12 | - theme: brand
13 | text: Get Started
14 | link: /getting-started/introduction
15 | - theme: alt
16 | text: View on GitHub
17 | link: https://github.com/rmunate/SpellNumber
18 | - theme: alt
19 | text: View on Youtube
20 | link: https://www.youtube.com/watch?v=jm7_ypPZbjk&list=PL-SK4hjbvgxLmNUAyDpUa44cCIx4hVTqE
21 |
22 | features:
23 | - icon: 📝
24 | title: Convert to Words
25 | details: Effortlessly convert numbers to words. Choose whether you want to translate an integer or a floating-point number; we're ready for any scenario.
26 | - icon: 💵
27 | title: Words in Currency Format
28 | details: Represent a currency value in words easily by specifying the currency and its fraction.
29 | - icon: 🔢
30 | title: Convert to Ordinals
31 | details: Planning to use the values for ordering? We've got you covered—easily transform your values into ordinal numbers.
32 | ---
--------------------------------------------------------------------------------
/docs/public/css/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --vp-home-hero-name-color: #09a292;
3 | --vp-button-brand-border: #427d84;
4 | --vp-button-brand-bg: #4c99a2;
5 | --vp-button-brand-hover-bg: #01403d;
6 | --vp-c-brand-1: #09a292;
7 | }
8 |
9 | .tagline{
10 | font-size: 22px !important;
11 | }
--------------------------------------------------------------------------------
/docs/public/img/laravel-red.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/public/img/laravel_black.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/docs/public/img/logo-full-scream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rmunate/SpellNumber/22b4bd162b016628f6f8a58bccd53f289611e1f9/docs/public/img/logo-full-scream.png
--------------------------------------------------------------------------------
/docs/public/img/logo-github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rmunate/SpellNumber/22b4bd162b016628f6f8a58bccd53f289611e1f9/docs/public/img/logo-github.png
--------------------------------------------------------------------------------
/docs/public/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rmunate/SpellNumber/22b4bd162b016628f6f8a58bccd53f289611e1f9/docs/public/img/logo.png
--------------------------------------------------------------------------------
/docs/usage/config-custom-callback.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Callback
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Callback
8 |
9 | In the same configuration file `spell-number.php`, you will have a callback that you can use to do any type of treatment at the output of the packet processing.
10 |
11 | ``` php
12 | return [
13 | //...
14 | 'callback_output' => function ($data) {
15 |
16 | // Your logic here...
17 |
18 | return $data->getWords();
19 | },
20 | ]
21 | ```
22 |
23 | Inside the callback you will have a variable `$data`, which contains the necessary information so that you can execute any type of process within this space.
24 |
25 | If you print the $data variable, you will find an instance of the `Rmunate\Utilities\Callback\DataResponse` object that allows you to access the following values.
26 |
27 | ``` php
28 | dd($data);
29 |
30 | // Rmunate\Utilities\Callback\DataResponse {
31 | // #method: "toMoney"
32 | // #type: "double"
33 | // #lang: "en"
34 | // #locale: "en_US"
35 | // #currency: "Dollars"
36 | // #fraction: "Cents"
37 | // +value: "12345.230"
38 | // +words: "Twelve Thousand Three Hundred Forty-Five Dollars And Two Hundred Thirty Cents"
39 | // }
40 | ```
41 |
42 | Easily access any property of this object with the syntax `$data->words`, likewise, this object contains getters to obtain the values if you prefer it that way `$data->getWords()`.
43 |
44 | ::: warning IMPORTANT
45 | Remember that you must return the final value after executing all the actions you want on the package output values.
46 | `return $value`.
47 |
48 |
--------------------------------------------------------------------------------
/docs/usage/config-file.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Config File
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Config File
8 |
9 | Since version 4.0 of the package, you will have the option to configure your environment so that the translations are easier to write in your controllers or classes, now you will have a file inside the `config` folder that will allow you to adjust by default the values to be used in the conversions.
10 |
11 | You will also have a unique functionality, where you can create your own logic for any output of the values processed in the package.
12 |
13 | ## Export file from vendor to project
14 |
15 | To export the configuration file from the vendor to the `config` folder, you can use the command:
16 |
17 | ``` bash
18 | php artisan vendor:publish --provider="Rmunate\\Utilities\\Providers\\SpellNumberProvider" --tag="config"
19 | ```
20 |
21 | ## Locale.
22 |
23 | Now that you have the `spell-number.php` file in the `config` folder, you can adjust the language that will be used for all translations of the package from numbers to letters, avoiding having to use it when invoking the use of the library.
24 |
25 | ``` php
26 | return [
27 | //...
28 | 'default' => [
29 | //...
30 | 'locale' => 'en',
31 | //...
32 | ]
33 | ]
34 | ```
35 |
36 | In the index `locale` you can assign the one you are going to use globally.
37 |
38 | ## Specific Locale
39 |
40 | By default the package only works with the list of supported languages, a list that can be obtained with the `SpellNumber::getAvailableLocales()` method, now if what you are looking for is to use a more precise `locale`, such as `es_CO`, `es_MX`,`en_US`, in that case you can leave this configuration defined to avoid having to pass the constant `SpellNumber::SPECIFIC_LOCALE` in the `->locale(...)` method.
41 |
42 | ``` php
43 | return [
44 | //...
45 | 'default' => [
46 | //...
47 | 'specific_locale' => true, //false (default)
48 | //...
49 | ]
50 | ]
51 | ```
52 |
53 | ## Currency Values
54 |
55 | Just as you can set the global translation language, you can also define the currency values that should be used in all library processing outputs.
56 |
57 | ``` php
58 | return [
59 | //...
60 | 'default' => [
61 | //...
62 | 'currency' => 'dollars',
63 | //...
64 | 'fraction' => 'cents',
65 | //...
66 | ]
67 | ]
68 | ```
69 |
70 | ## Output type ordinal texts
71 |
72 | If you are going to use the package to generate ordinal values, in that case you can also determine a global output for all calls of the method, for that you can define the output mode of the ordinal text from the configuration file, this avoids you having to go through the `SpellNumber::ORDINAL_DEFAULT`, `SpellNumber::ORDINAL_MALE`, `SpellNumber::ORDINAL_FEMALE` constants in the `->toOrdinal()` method.
73 |
74 | ``` php
75 | return [
76 | //...
77 | 'default' => [
78 | //...
79 | 'ordinal_output' => 'default', // 'default', 'male', 'female'
80 | //...
81 | ]
82 | ]
83 | ```
84 |
85 | ## Replacements
86 |
87 | Some people around the world have seen that some small fragments of the packet processing outputs must conform to the current language of the country or region, usually they are small fragments that could be replaced by a specific term or form of writing, for that you now have the possibility of defining all the replacements of text fragments that you consider necessary.
88 |
89 | Relying on the structure of an associative array, you will put the value to be searched as an index and the text to be assigned as its replacement as a value.
90 |
91 | The primary value must be there, that is, "es" instead of "es_MX" or similar.
92 |
93 | ``` php
94 | return [
95 | //...
96 | 'replacements' => [
97 | 'es' => [
98 | 'uno' => 'un',
99 | ],
100 | ],
101 | ]
102 | ```
103 |
104 | You must define the language on which the replacement should be applied in all the outputs of the internal processing of the package.
105 |
106 | ## Callback
107 |
108 | If what you would like is to have a programmable way to modify the output of the package value, in that case this solution is what you need.
109 |
110 | Go to the next page =>
--------------------------------------------------------------------------------
/docs/usage/languages-available.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Supported Languages
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Supported Languages
8 |
9 | We currently have 11 preset languages to easily work with this package. _Although you can use other configurations with arbitrary outputs_, we list the pre-configured languages below:
10 |
11 | - German.
12 | - English.
13 | - Spanish.
14 | - Farsi.
15 | - French.
16 | - Hindi.
17 | - Italian.
18 | - Polish.
19 | - Portuguese.
20 | - Romanian.
21 | - Vietnamese.
22 |
23 | If you want to get the supported languages directly from the package, you have two ways to do it.
24 |
25 | ## Available Locales
26 | Execute the method `getAvailableLocales`, as output it will give you an array with the available values.
27 |
28 | ```php
29 | use Rmunate\Utilities\SpellNumber;
30 |
31 | SpellNumber::getAvailableLocales();
32 |
33 | // array:10 [▼
34 | // 0 => "de"
35 | // 1 => "en"
36 | // 2 => "es"
37 | // 3 => "fa"
38 | // 4 => "fr"
39 | // 5 => "hi"
40 | // 6 => "it"
41 | // 7 => "pl"
42 | // 8 => "pt"
43 | // 9 => "ro"
44 | // 10 => "vi"
45 | // ]
46 | ```
47 |
48 | ## Available Languages
49 |
50 | Execute the method `getAvailableLanguages`, as output it will give you an associative array with the values of available languages.
51 |
52 | ```php
53 | use Rmunate\Utilities\SpellNumber;
54 |
55 | SpellNumber::getAvailableLanguages();
56 |
57 | // array:10 [▼
58 | // "de" => "German"
59 | // "en" => "English"
60 | // "es" => "Spanish"
61 | // "fa" => "Farsi"
62 | // "fr" => "French"
63 | // "hi" => "Hindi"
64 | // "it" => "Italian"
65 | // "pl" => "Polish"
66 | // "pt" => "Portuguese"
67 | // "ro" => "Romanian"
68 | // "vi" => "Vietnamese"
69 | // ]
70 | ```
71 |
72 | ## Other Locales
73 |
74 | If you would like to try a language other than the 10 previously mentioned, you can consult the different values that you can supply to the package to try to generate the output translated to said area and language.
75 |
76 | In order to use any of these options, you must use the constant `SpellNumber::SPECIFIC_LOCALE` in the `locale` method, example `->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)`.
77 |
78 |
79 | ```php
80 | use Rmunate\Utilities\SpellNumber;
81 |
82 | SpellNumber::getAllLocales();
83 |
84 | // array:805 [▼
85 | // 0 => "af"
86 | // 1 => "af_NA"
87 | // 2 => "af_ZA"
88 | // 3 => "agq"
89 | // 4 => "agq_CM"
90 | // 5 => "ak"
91 | // 6 => "ak_GH"
92 | // 7 => "am"
93 | // 8 => "am_ET"
94 | // 9 => "ar"
95 | // 10 => "ar_001"
96 | // ...
97 | // ]
98 | ```
--------------------------------------------------------------------------------
/docs/usage/macroable.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Macroable
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Macroable
8 |
9 | You likely have excellent ideas for methods that could greatly benefit from the capabilities of **SpellNumber**. We encourage you to create them yourself.
10 |
11 | ## Creating a Macro
12 |
13 | To develop a custom method, you can establish a new provider and register it within your application, following the guidelines in the [Laravel Documentation](https://laravel.com/docs/10.x/providers). This approach can lead to a more organized and clear code structure. For this guide's purposes, we'll utilize the `AppServiceProvider`, which is readily available and located at `app/Providers/AppServiceProvider.php`.
14 |
15 | Within the `register()` method of the Provider, you can craft your custom method. For practical demonstration, let's create the `toLettersWithSymbol` method. This method will transform the supplied value into words, followed by the currency symbol and its abbreviation. The output will be **'Two hundred - $MXN'**.
16 |
17 | ```php
18 | namespace App\Providers;
19 |
20 | use Rmunate\Utilities\SpellNumber;
21 | use Illuminate\Support\ServiceProvider;
22 |
23 | class AppServiceProvider extends ServiceProvider
24 | {
25 | /**
26 | * Register any application services.
27 | */
28 | public function register(): void
29 | {
30 | SpellNumber::macro('toLettersWithSymbol', function (string $symbol) {
31 |
32 | $value = $this->spell(SpellNumber::TO_LETTERS);
33 |
34 | return "$value - $symbol";
35 | });
36 | }
37 | }
38 | ```
39 |
40 | ## The Spell Method
41 |
42 | If you observe, the "spell" method is used within the constructed macro. This method is exclusively available in this context and cannot be utilized elsewhere. It facilitates the effortless conversion of the provided value into words, as needed.
43 |
44 | To Letters:
45 | ```php
46 | $this->spell(SpellNumber::TO_LETTERS)
47 | ```
48 |
49 | To Money Format:
50 | ```php
51 | $this->spell(SpellNumber::TO_MONEY)
52 | ```
53 |
54 | To Ordinal Text:
55 | ```php
56 | $this->spell(SpellNumber::TO_ORDINAL, SpellNumber::ORDINAL_DEFAULT)
57 | ```
58 |
59 | ## How to Use My Macro
60 |
61 | Now that you have created your macro within the service provider, simply call it like an original method of the SpellNumber class.
62 |
63 | ```php
64 | SpellNumber::value(200)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->toLettersWithSymbol('$MXN')
65 | // "Doscientos - $MXN"
66 | ```
67 |
68 | You now possess the ability to create unique solutions within your applications.
--------------------------------------------------------------------------------
/docs/usage/numbers-to-letters.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Numbers To Letters
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Numbers To Letters
8 |
9 | ## Method Value
10 |
11 | ### Integers
12 |
13 | You can easily convert whole numbers to words by defining the locale to be applied. If you do not define a locale, "en" (English) will be applied by default. Remember that if you export the vendor configuration file, it will not require this definition.
14 |
15 | ```php
16 | use Rmunate\Utilities\SpellNumber;
17 |
18 | SpellNumber::value(100)->locale('en')->toLetters();
19 | // "one hundred"
20 |
21 | SpellNumber::value(100)->locale('es')->toLetters();
22 | // "cien"
23 |
24 | SpellNumber::value(100)->locale('fa')->toLetters();
25 | // "صد"
26 |
27 | SpellNumber::value(100)->locale('hi')->toLetters();
28 | // "एक सौ"
29 | ```
30 |
31 | ### Floating Point
32 |
33 | If required, you can pass a floating point number as an argument to convert it to words. Only the first two digits after the floating point will be taken.
34 |
35 | ```php
36 | use Rmunate\Utilities\SpellNumber;
37 |
38 | SpellNumber::value(123456789.12)->locale('en')->toLetters();
39 | // "one hundred twenty-three million four hundred fifty-six thousand seven hundred eighty-nine and twelve"
40 |
41 | SpellNumber::value(123456789.12)->locale('es')->toLetters();
42 | // "ciento veintitrés millones cuatrocientos cincuenta y seis mil setecientos ochenta y nueve con doce"
43 |
44 | SpellNumber::value(123456789.12)->locale('hi')->toLetters();
45 | // "बारह करोड़ चौंतीस लाख छप्पन हज़ार सात सौ नवासी और बारह"
46 | ```
47 |
48 | ## Method Integer
49 |
50 | You can also rely on the `Integer` method to define that the input is a new integer.
51 | Remember to ensure that the input value is of type `int`.
52 |
53 | ```php
54 | use Rmunate\Utilities\SpellNumber;
55 |
56 | SpellNumber::integer(100)->locale('en')->toLetters();
57 | // "one hundred"
58 |
59 | SpellNumber::integer(100)->locale('es')->toLetters();
60 | // "cien"
61 | ```
62 |
63 | ## Method Float
64 |
65 | Now, if you require it to be translated into letters of more than two decimal places, the solution may be to use the Float method. This method necessarily receives a string value that allows the library to read the complete value sent after the floating point.
66 |
67 | ```php
68 | use Rmunate\Utilities\SpellNumber;
69 |
70 | SpellNumber::float('12345.230')->locale('en')->toLetters();
71 | // "twelve thousand three hundred forty-five and two hundred thirty"
72 |
73 | SpellNumber::float('12345.230')->locale('es')->toLetters();
74 | // "doce mil trescientos cuarenta y cinco con doscientos treinta"
75 | ```
76 |
77 | ## Especific Locale
78 |
79 | If you want to use a specific locale, you should always use the constant `SpellNumber::SPECIFIC_LOCALE`
80 |
81 | ```php
82 | use Rmunate\Utilities\SpellNumber;
83 |
84 | SpellNumber::value(100)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->toLetters();
85 | // "cien"
86 |
87 | SpellNumber::integer(100)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->toLetters();
88 | // "cien"
89 |
90 | SpellNumber::float('12345.230')->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->toLetters();
91 | // "doce mil trescientos cuarenta y cinco con doscientos treinta"
92 | ```
--------------------------------------------------------------------------------
/docs/usage/numbers-to-money.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Numbers To Money
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Numbers To Money
8 |
9 | ## Method Value
10 |
11 | ### Integers
12 |
13 | It is very easy to use this solution for systems where you require the value more than in letters, with the specified currency structure.
14 | If you require that an integer have this transformation, you can do it in the following way.
15 |
16 | ```php
17 | SpellNumber::value(100)->locale('en')->currency('Dollars')->toMoney();
18 | // "one hundred dollars"
19 |
20 | SpellNumber::value(100)->locale('es')->currency('Pesos')->toMoney();
21 | // "cien pesos"
22 |
23 | SpellNumber::value(100)->locale('fa')->currency('تومان')->toMoney();
24 | // "صد تومان"
25 |
26 | SpellNumber::value(100)->locale('hi')->currency('रूपये')->toMoney();
27 | // "एक सौ रूपये"
28 | ```
29 |
30 | ### Floating Point
31 |
32 | You can also pass a floating point number as an argument to convert it into words in currency format. Only the first two digits after the floating point will be taken.
33 |
34 | This method can be useful for invoices, receipts, and similar scenarios. Obtain the supplied value in currency format.
35 |
36 | ```php
37 | SpellNumber::value(100.12)->locale('en')->currency('Dollars')->fraction('Cents')->toMoney();
38 | // "one hundred dollars and twelve cents"
39 |
40 | SpellNumber::value(100.12)->locale('es')->currency('Pesos')->fraction('Centavos')->toMoney();
41 | // "cien pesos con doce centavos"
42 |
43 | SpellNumber::value(100.12)->locale('hi')->currency('रूपये')->fraction('पैसे')->toMoney();
44 | // "एक सौ रूपये और बारह पैसे"
45 |
46 | SpellNumber::value(100.65)->locale('pl')->currency('złotych')->fraction('groszy')->toMoney();
47 | // "sto złotych i sześćdziesiąt pięć groszy"
48 | ```
49 |
50 | ## Method Integer
51 |
52 | You can also rely on the `Integer` method to define that the input is a new integer.
53 | Remember to ensure that the input value is of type `int`.
54 |
55 | ```php
56 | SpellNumber::integer(100)->locale('es')->currency('Pesos')->toMoney();
57 | // "cien pesos"
58 |
59 | SpellNumber::integer(100)->locale('en')->currency('Dollars')->toMoney();
60 | // "one hundred dollars"
61 | ```
62 |
63 | ## Method Float
64 |
65 | Now, if you require it to be translated into letters of more than two decimal places, the solution may be to use the Float method. This method necessarily receives a string value that allows the library to read the complete value sent after the floating point.
66 |
67 | ```php
68 | SpellNumber::float('12345.230')->locale('es')->currency('Pesos')->fraction('Centavos')->toMoney();
69 | // "doce mil trescientos cuarenta y cinco pesos con doscientos treinta centavos"
70 |
71 | SpellNumber::float('12345.230')->locale('en')->currency('Dollars')->fraction('Cents')->toMoney();
72 | // "twelve thousand three hundred forty-five dollars and two hundred thirty cents"
73 | ```
74 |
75 | ## Especific Locale
76 |
77 | If you want to use a specific locale, you should always use the constant `SpellNumber::SPECIFIC_LOCALE`
78 |
79 | ```php
80 | use Rmunate\Utilities\SpellNumber;
81 |
82 | SpellNumber::value(100)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->currency('Pesos')->toMoney();
83 | // "cien pesos"
84 |
85 | SpellNumber::integer(100)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->currency('Pesos')->toMoney();
86 | // "cien pesos"
87 |
88 | SpellNumber::float('12345.230')->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->currency('Pesos')->fraction('Centavos')->toMoney();
89 | // "doce mil trescientos cuarenta y cinco pesos con doscientos treinta centavos"
90 | ```
--------------------------------------------------------------------------------
/docs/usage/numbers-to-ordinal.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Numbers To Ordinal
3 | editLink: true
4 | outline: deep
5 | ---
6 |
7 | # Numbers To Ordinal
8 |
9 | You may need to list some data within your system, if so, this section is your solution.
10 |
11 | This package included the option to use ordinal numbers for this purpose.
12 |
13 | You can only use this method with integers, remember to ensure that the value meets this type, otherwise we may have unexpected responses.
14 |
15 | ## Method Value
16 |
17 | You can easily convert integers. If you do not define a locale, "en" (English) will be applied by default. Remember that if you export the provider configuration file, it will not require this definition.
18 |
19 | ```php
20 | use Rmunate\Utilities\SpellNumber;
21 |
22 | SpellNumber::value(2)->locale('en')->toOrdinal();
23 | // "second"
24 |
25 | SpellNumber::value(2)->locale('en')->toOrdinal(SpellNumber::ORDINAL_DEFAULT);
26 | // "second"
27 |
28 | SpellNumber::value(2)->locale('es')->toOrdinal(SpellNumber::ORDINAL_MALE);
29 | // "segundo"
30 |
31 | SpellNumber::value(2)->locale('es')->toOrdinal(SpellNumber::ORDINAL_FEMALE);
32 | // "segunda"
33 | ```
34 |
35 | ## Method Integer
36 |
37 | You can also rely on the `Integer` method to define that the input is a new integer.
38 | Remember to ensure that the input value is of type `int`.
39 |
40 | ```php
41 | use Rmunate\Utilities\SpellNumber;
42 |
43 | SpellNumber::integer(2)->locale('en')->toOrdinal();
44 | // "second"
45 |
46 | SpellNumber::integer(2)->locale('en')->toOrdinal(SpellNumber::ORDINAL_DEFAULT);
47 | // "second"
48 |
49 | SpellNumber::integer(2)->locale('es')->toOrdinal(SpellNumber::ORDINAL_MALE);
50 | // "segundo"
51 |
52 | SpellNumber::integer(2)->locale('es')->toOrdinal(SpellNumber::ORDINAL_FEMALE);
53 | // "segunda"
54 | ```
55 |
56 | ## Especific Locale
57 |
58 | If you want to use a specific locale, you should always use the constant `SpellNumber::SPECIFIC_LOCALE`
59 |
60 | ```php
61 | use Rmunate\Utilities\SpellNumber;
62 |
63 | SpellNumber::value(2)->locale('en_US', SpellNumber::SPECIFIC_LOCALE)->toOrdinal();
64 | // "second"
65 |
66 | SpellNumber::integer(2)->locale('es_MX', SpellNumber::SPECIFIC_LOCALE)->toOrdinal(SpellNumber::ORDINAL_FEMALE)
67 | // "segunda"
68 | ```
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SpellNumber",
3 | "lockfileVersion": 3,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "devDependencies": {
8 | "vitepress": "^1.0.0-rc.13"
9 | }
10 | },
11 | "node_modules/@algolia/autocomplete-core": {
12 | "version": "1.9.3",
13 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz",
14 | "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==",
15 | "dev": true,
16 | "dependencies": {
17 | "@algolia/autocomplete-plugin-algolia-insights": "1.9.3",
18 | "@algolia/autocomplete-shared": "1.9.3"
19 | }
20 | },
21 | "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
22 | "version": "1.9.3",
23 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz",
24 | "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==",
25 | "dev": true,
26 | "dependencies": {
27 | "@algolia/autocomplete-shared": "1.9.3"
28 | },
29 | "peerDependencies": {
30 | "search-insights": ">= 1 < 3"
31 | }
32 | },
33 | "node_modules/@algolia/autocomplete-preset-algolia": {
34 | "version": "1.9.3",
35 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz",
36 | "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==",
37 | "dev": true,
38 | "dependencies": {
39 | "@algolia/autocomplete-shared": "1.9.3"
40 | },
41 | "peerDependencies": {
42 | "@algolia/client-search": ">= 4.9.1 < 6",
43 | "algoliasearch": ">= 4.9.1 < 6"
44 | }
45 | },
46 | "node_modules/@algolia/autocomplete-shared": {
47 | "version": "1.9.3",
48 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz",
49 | "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==",
50 | "dev": true,
51 | "peerDependencies": {
52 | "@algolia/client-search": ">= 4.9.1 < 6",
53 | "algoliasearch": ">= 4.9.1 < 6"
54 | }
55 | },
56 | "node_modules/@algolia/cache-browser-local-storage": {
57 | "version": "4.20.0",
58 | "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz",
59 | "integrity": "sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==",
60 | "dev": true,
61 | "dependencies": {
62 | "@algolia/cache-common": "4.20.0"
63 | }
64 | },
65 | "node_modules/@algolia/cache-common": {
66 | "version": "4.20.0",
67 | "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.20.0.tgz",
68 | "integrity": "sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==",
69 | "dev": true
70 | },
71 | "node_modules/@algolia/cache-in-memory": {
72 | "version": "4.20.0",
73 | "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz",
74 | "integrity": "sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==",
75 | "dev": true,
76 | "dependencies": {
77 | "@algolia/cache-common": "4.20.0"
78 | }
79 | },
80 | "node_modules/@algolia/client-account": {
81 | "version": "4.20.0",
82 | "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.20.0.tgz",
83 | "integrity": "sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==",
84 | "dev": true,
85 | "dependencies": {
86 | "@algolia/client-common": "4.20.0",
87 | "@algolia/client-search": "4.20.0",
88 | "@algolia/transporter": "4.20.0"
89 | }
90 | },
91 | "node_modules/@algolia/client-analytics": {
92 | "version": "4.20.0",
93 | "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.20.0.tgz",
94 | "integrity": "sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==",
95 | "dev": true,
96 | "dependencies": {
97 | "@algolia/client-common": "4.20.0",
98 | "@algolia/client-search": "4.20.0",
99 | "@algolia/requester-common": "4.20.0",
100 | "@algolia/transporter": "4.20.0"
101 | }
102 | },
103 | "node_modules/@algolia/client-common": {
104 | "version": "4.20.0",
105 | "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.20.0.tgz",
106 | "integrity": "sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==",
107 | "dev": true,
108 | "dependencies": {
109 | "@algolia/requester-common": "4.20.0",
110 | "@algolia/transporter": "4.20.0"
111 | }
112 | },
113 | "node_modules/@algolia/client-personalization": {
114 | "version": "4.20.0",
115 | "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.20.0.tgz",
116 | "integrity": "sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==",
117 | "dev": true,
118 | "dependencies": {
119 | "@algolia/client-common": "4.20.0",
120 | "@algolia/requester-common": "4.20.0",
121 | "@algolia/transporter": "4.20.0"
122 | }
123 | },
124 | "node_modules/@algolia/client-search": {
125 | "version": "4.20.0",
126 | "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.20.0.tgz",
127 | "integrity": "sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==",
128 | "dev": true,
129 | "dependencies": {
130 | "@algolia/client-common": "4.20.0",
131 | "@algolia/requester-common": "4.20.0",
132 | "@algolia/transporter": "4.20.0"
133 | }
134 | },
135 | "node_modules/@algolia/logger-common": {
136 | "version": "4.20.0",
137 | "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.20.0.tgz",
138 | "integrity": "sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==",
139 | "dev": true
140 | },
141 | "node_modules/@algolia/logger-console": {
142 | "version": "4.20.0",
143 | "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.20.0.tgz",
144 | "integrity": "sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==",
145 | "dev": true,
146 | "dependencies": {
147 | "@algolia/logger-common": "4.20.0"
148 | }
149 | },
150 | "node_modules/@algolia/requester-browser-xhr": {
151 | "version": "4.20.0",
152 | "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz",
153 | "integrity": "sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==",
154 | "dev": true,
155 | "dependencies": {
156 | "@algolia/requester-common": "4.20.0"
157 | }
158 | },
159 | "node_modules/@algolia/requester-common": {
160 | "version": "4.20.0",
161 | "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.20.0.tgz",
162 | "integrity": "sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==",
163 | "dev": true
164 | },
165 | "node_modules/@algolia/requester-node-http": {
166 | "version": "4.20.0",
167 | "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz",
168 | "integrity": "sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==",
169 | "dev": true,
170 | "dependencies": {
171 | "@algolia/requester-common": "4.20.0"
172 | }
173 | },
174 | "node_modules/@algolia/transporter": {
175 | "version": "4.20.0",
176 | "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.20.0.tgz",
177 | "integrity": "sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==",
178 | "dev": true,
179 | "dependencies": {
180 | "@algolia/cache-common": "4.20.0",
181 | "@algolia/logger-common": "4.20.0",
182 | "@algolia/requester-common": "4.20.0"
183 | }
184 | },
185 | "node_modules/@babel/parser": {
186 | "version": "7.23.0",
187 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
188 | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
189 | "dev": true,
190 | "bin": {
191 | "parser": "bin/babel-parser.js"
192 | },
193 | "engines": {
194 | "node": ">=6.0.0"
195 | }
196 | },
197 | "node_modules/@docsearch/css": {
198 | "version": "3.5.2",
199 | "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz",
200 | "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==",
201 | "dev": true
202 | },
203 | "node_modules/@docsearch/js": {
204 | "version": "3.5.2",
205 | "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.5.2.tgz",
206 | "integrity": "sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==",
207 | "dev": true,
208 | "dependencies": {
209 | "@docsearch/react": "3.5.2",
210 | "preact": "^10.0.0"
211 | }
212 | },
213 | "node_modules/@docsearch/react": {
214 | "version": "3.5.2",
215 | "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz",
216 | "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==",
217 | "dev": true,
218 | "dependencies": {
219 | "@algolia/autocomplete-core": "1.9.3",
220 | "@algolia/autocomplete-preset-algolia": "1.9.3",
221 | "@docsearch/css": "3.5.2",
222 | "algoliasearch": "^4.19.1"
223 | },
224 | "peerDependencies": {
225 | "@types/react": ">= 16.8.0 < 19.0.0",
226 | "react": ">= 16.8.0 < 19.0.0",
227 | "react-dom": ">= 16.8.0 < 19.0.0",
228 | "search-insights": ">= 1 < 3"
229 | },
230 | "peerDependenciesMeta": {
231 | "@types/react": {
232 | "optional": true
233 | },
234 | "react": {
235 | "optional": true
236 | },
237 | "react-dom": {
238 | "optional": true
239 | },
240 | "search-insights": {
241 | "optional": true
242 | }
243 | }
244 | },
245 | "node_modules/@esbuild/android-arm": {
246 | "version": "0.18.20",
247 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
248 | "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
249 | "cpu": [
250 | "arm"
251 | ],
252 | "dev": true,
253 | "optional": true,
254 | "os": [
255 | "android"
256 | ],
257 | "engines": {
258 | "node": ">=12"
259 | }
260 | },
261 | "node_modules/@esbuild/android-arm64": {
262 | "version": "0.18.20",
263 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
264 | "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
265 | "cpu": [
266 | "arm64"
267 | ],
268 | "dev": true,
269 | "optional": true,
270 | "os": [
271 | "android"
272 | ],
273 | "engines": {
274 | "node": ">=12"
275 | }
276 | },
277 | "node_modules/@esbuild/android-x64": {
278 | "version": "0.18.20",
279 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
280 | "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
281 | "cpu": [
282 | "x64"
283 | ],
284 | "dev": true,
285 | "optional": true,
286 | "os": [
287 | "android"
288 | ],
289 | "engines": {
290 | "node": ">=12"
291 | }
292 | },
293 | "node_modules/@esbuild/darwin-arm64": {
294 | "version": "0.18.20",
295 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
296 | "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
297 | "cpu": [
298 | "arm64"
299 | ],
300 | "dev": true,
301 | "optional": true,
302 | "os": [
303 | "darwin"
304 | ],
305 | "engines": {
306 | "node": ">=12"
307 | }
308 | },
309 | "node_modules/@esbuild/darwin-x64": {
310 | "version": "0.18.20",
311 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
312 | "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
313 | "cpu": [
314 | "x64"
315 | ],
316 | "dev": true,
317 | "optional": true,
318 | "os": [
319 | "darwin"
320 | ],
321 | "engines": {
322 | "node": ">=12"
323 | }
324 | },
325 | "node_modules/@esbuild/freebsd-arm64": {
326 | "version": "0.18.20",
327 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
328 | "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
329 | "cpu": [
330 | "arm64"
331 | ],
332 | "dev": true,
333 | "optional": true,
334 | "os": [
335 | "freebsd"
336 | ],
337 | "engines": {
338 | "node": ">=12"
339 | }
340 | },
341 | "node_modules/@esbuild/freebsd-x64": {
342 | "version": "0.18.20",
343 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
344 | "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
345 | "cpu": [
346 | "x64"
347 | ],
348 | "dev": true,
349 | "optional": true,
350 | "os": [
351 | "freebsd"
352 | ],
353 | "engines": {
354 | "node": ">=12"
355 | }
356 | },
357 | "node_modules/@esbuild/linux-arm": {
358 | "version": "0.18.20",
359 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
360 | "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
361 | "cpu": [
362 | "arm"
363 | ],
364 | "dev": true,
365 | "optional": true,
366 | "os": [
367 | "linux"
368 | ],
369 | "engines": {
370 | "node": ">=12"
371 | }
372 | },
373 | "node_modules/@esbuild/linux-arm64": {
374 | "version": "0.18.20",
375 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
376 | "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
377 | "cpu": [
378 | "arm64"
379 | ],
380 | "dev": true,
381 | "optional": true,
382 | "os": [
383 | "linux"
384 | ],
385 | "engines": {
386 | "node": ">=12"
387 | }
388 | },
389 | "node_modules/@esbuild/linux-ia32": {
390 | "version": "0.18.20",
391 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
392 | "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
393 | "cpu": [
394 | "ia32"
395 | ],
396 | "dev": true,
397 | "optional": true,
398 | "os": [
399 | "linux"
400 | ],
401 | "engines": {
402 | "node": ">=12"
403 | }
404 | },
405 | "node_modules/@esbuild/linux-loong64": {
406 | "version": "0.18.20",
407 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
408 | "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
409 | "cpu": [
410 | "loong64"
411 | ],
412 | "dev": true,
413 | "optional": true,
414 | "os": [
415 | "linux"
416 | ],
417 | "engines": {
418 | "node": ">=12"
419 | }
420 | },
421 | "node_modules/@esbuild/linux-mips64el": {
422 | "version": "0.18.20",
423 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
424 | "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
425 | "cpu": [
426 | "mips64el"
427 | ],
428 | "dev": true,
429 | "optional": true,
430 | "os": [
431 | "linux"
432 | ],
433 | "engines": {
434 | "node": ">=12"
435 | }
436 | },
437 | "node_modules/@esbuild/linux-ppc64": {
438 | "version": "0.18.20",
439 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
440 | "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
441 | "cpu": [
442 | "ppc64"
443 | ],
444 | "dev": true,
445 | "optional": true,
446 | "os": [
447 | "linux"
448 | ],
449 | "engines": {
450 | "node": ">=12"
451 | }
452 | },
453 | "node_modules/@esbuild/linux-riscv64": {
454 | "version": "0.18.20",
455 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
456 | "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
457 | "cpu": [
458 | "riscv64"
459 | ],
460 | "dev": true,
461 | "optional": true,
462 | "os": [
463 | "linux"
464 | ],
465 | "engines": {
466 | "node": ">=12"
467 | }
468 | },
469 | "node_modules/@esbuild/linux-s390x": {
470 | "version": "0.18.20",
471 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
472 | "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
473 | "cpu": [
474 | "s390x"
475 | ],
476 | "dev": true,
477 | "optional": true,
478 | "os": [
479 | "linux"
480 | ],
481 | "engines": {
482 | "node": ">=12"
483 | }
484 | },
485 | "node_modules/@esbuild/linux-x64": {
486 | "version": "0.18.20",
487 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
488 | "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
489 | "cpu": [
490 | "x64"
491 | ],
492 | "dev": true,
493 | "optional": true,
494 | "os": [
495 | "linux"
496 | ],
497 | "engines": {
498 | "node": ">=12"
499 | }
500 | },
501 | "node_modules/@esbuild/netbsd-x64": {
502 | "version": "0.18.20",
503 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
504 | "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
505 | "cpu": [
506 | "x64"
507 | ],
508 | "dev": true,
509 | "optional": true,
510 | "os": [
511 | "netbsd"
512 | ],
513 | "engines": {
514 | "node": ">=12"
515 | }
516 | },
517 | "node_modules/@esbuild/openbsd-x64": {
518 | "version": "0.18.20",
519 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
520 | "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
521 | "cpu": [
522 | "x64"
523 | ],
524 | "dev": true,
525 | "optional": true,
526 | "os": [
527 | "openbsd"
528 | ],
529 | "engines": {
530 | "node": ">=12"
531 | }
532 | },
533 | "node_modules/@esbuild/sunos-x64": {
534 | "version": "0.18.20",
535 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
536 | "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
537 | "cpu": [
538 | "x64"
539 | ],
540 | "dev": true,
541 | "optional": true,
542 | "os": [
543 | "sunos"
544 | ],
545 | "engines": {
546 | "node": ">=12"
547 | }
548 | },
549 | "node_modules/@esbuild/win32-arm64": {
550 | "version": "0.18.20",
551 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
552 | "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
553 | "cpu": [
554 | "arm64"
555 | ],
556 | "dev": true,
557 | "optional": true,
558 | "os": [
559 | "win32"
560 | ],
561 | "engines": {
562 | "node": ">=12"
563 | }
564 | },
565 | "node_modules/@esbuild/win32-ia32": {
566 | "version": "0.18.20",
567 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
568 | "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
569 | "cpu": [
570 | "ia32"
571 | ],
572 | "dev": true,
573 | "optional": true,
574 | "os": [
575 | "win32"
576 | ],
577 | "engines": {
578 | "node": ">=12"
579 | }
580 | },
581 | "node_modules/@esbuild/win32-x64": {
582 | "version": "0.18.20",
583 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
584 | "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
585 | "cpu": [
586 | "x64"
587 | ],
588 | "dev": true,
589 | "optional": true,
590 | "os": [
591 | "win32"
592 | ],
593 | "engines": {
594 | "node": ">=12"
595 | }
596 | },
597 | "node_modules/@jridgewell/sourcemap-codec": {
598 | "version": "1.4.15",
599 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
600 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
601 | "dev": true
602 | },
603 | "node_modules/@types/linkify-it": {
604 | "version": "3.0.4",
605 | "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.4.tgz",
606 | "integrity": "sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==",
607 | "dev": true
608 | },
609 | "node_modules/@types/markdown-it": {
610 | "version": "13.0.4",
611 | "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.4.tgz",
612 | "integrity": "sha512-FAIUdEXrCDnQmAAmJC+UeW/3p0eCI4QZ/+W0lX/h83VD3v78IgTFYftjnAeXS8H0g4PFQCgipc51cQDA8tjgLw==",
613 | "dev": true,
614 | "dependencies": {
615 | "@types/linkify-it": "*",
616 | "@types/mdurl": "*"
617 | }
618 | },
619 | "node_modules/@types/mdurl": {
620 | "version": "1.0.4",
621 | "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.4.tgz",
622 | "integrity": "sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==",
623 | "dev": true
624 | },
625 | "node_modules/@types/web-bluetooth": {
626 | "version": "0.0.18",
627 | "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.18.tgz",
628 | "integrity": "sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==",
629 | "dev": true
630 | },
631 | "node_modules/@vue/compiler-core": {
632 | "version": "3.3.4",
633 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
634 | "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
635 | "dev": true,
636 | "dependencies": {
637 | "@babel/parser": "^7.21.3",
638 | "@vue/shared": "3.3.4",
639 | "estree-walker": "^2.0.2",
640 | "source-map-js": "^1.0.2"
641 | }
642 | },
643 | "node_modules/@vue/compiler-dom": {
644 | "version": "3.3.4",
645 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
646 | "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
647 | "dev": true,
648 | "dependencies": {
649 | "@vue/compiler-core": "3.3.4",
650 | "@vue/shared": "3.3.4"
651 | }
652 | },
653 | "node_modules/@vue/compiler-sfc": {
654 | "version": "3.3.4",
655 | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
656 | "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
657 | "dev": true,
658 | "dependencies": {
659 | "@babel/parser": "^7.20.15",
660 | "@vue/compiler-core": "3.3.4",
661 | "@vue/compiler-dom": "3.3.4",
662 | "@vue/compiler-ssr": "3.3.4",
663 | "@vue/reactivity-transform": "3.3.4",
664 | "@vue/shared": "3.3.4",
665 | "estree-walker": "^2.0.2",
666 | "magic-string": "^0.30.0",
667 | "postcss": "^8.1.10",
668 | "source-map-js": "^1.0.2"
669 | }
670 | },
671 | "node_modules/@vue/compiler-ssr": {
672 | "version": "3.3.4",
673 | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
674 | "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
675 | "dev": true,
676 | "dependencies": {
677 | "@vue/compiler-dom": "3.3.4",
678 | "@vue/shared": "3.3.4"
679 | }
680 | },
681 | "node_modules/@vue/devtools-api": {
682 | "version": "6.5.1",
683 | "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz",
684 | "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==",
685 | "dev": true
686 | },
687 | "node_modules/@vue/reactivity": {
688 | "version": "3.3.4",
689 | "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
690 | "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
691 | "dev": true,
692 | "dependencies": {
693 | "@vue/shared": "3.3.4"
694 | }
695 | },
696 | "node_modules/@vue/reactivity-transform": {
697 | "version": "3.3.4",
698 | "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
699 | "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
700 | "dev": true,
701 | "dependencies": {
702 | "@babel/parser": "^7.20.15",
703 | "@vue/compiler-core": "3.3.4",
704 | "@vue/shared": "3.3.4",
705 | "estree-walker": "^2.0.2",
706 | "magic-string": "^0.30.0"
707 | }
708 | },
709 | "node_modules/@vue/runtime-core": {
710 | "version": "3.3.4",
711 | "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
712 | "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
713 | "dev": true,
714 | "dependencies": {
715 | "@vue/reactivity": "3.3.4",
716 | "@vue/shared": "3.3.4"
717 | }
718 | },
719 | "node_modules/@vue/runtime-dom": {
720 | "version": "3.3.4",
721 | "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
722 | "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
723 | "dev": true,
724 | "dependencies": {
725 | "@vue/runtime-core": "3.3.4",
726 | "@vue/shared": "3.3.4",
727 | "csstype": "^3.1.1"
728 | }
729 | },
730 | "node_modules/@vue/server-renderer": {
731 | "version": "3.3.4",
732 | "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
733 | "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
734 | "dev": true,
735 | "dependencies": {
736 | "@vue/compiler-ssr": "3.3.4",
737 | "@vue/shared": "3.3.4"
738 | },
739 | "peerDependencies": {
740 | "vue": "3.3.4"
741 | }
742 | },
743 | "node_modules/@vue/shared": {
744 | "version": "3.3.4",
745 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
746 | "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==",
747 | "dev": true
748 | },
749 | "node_modules/@vueuse/core": {
750 | "version": "10.5.0",
751 | "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.5.0.tgz",
752 | "integrity": "sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==",
753 | "dev": true,
754 | "dependencies": {
755 | "@types/web-bluetooth": "^0.0.18",
756 | "@vueuse/metadata": "10.5.0",
757 | "@vueuse/shared": "10.5.0",
758 | "vue-demi": ">=0.14.6"
759 | },
760 | "funding": {
761 | "url": "https://github.com/sponsors/antfu"
762 | }
763 | },
764 | "node_modules/@vueuse/core/node_modules/vue-demi": {
765 | "version": "0.14.6",
766 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
767 | "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
768 | "dev": true,
769 | "hasInstallScript": true,
770 | "bin": {
771 | "vue-demi-fix": "bin/vue-demi-fix.js",
772 | "vue-demi-switch": "bin/vue-demi-switch.js"
773 | },
774 | "engines": {
775 | "node": ">=12"
776 | },
777 | "funding": {
778 | "url": "https://github.com/sponsors/antfu"
779 | },
780 | "peerDependencies": {
781 | "@vue/composition-api": "^1.0.0-rc.1",
782 | "vue": "^3.0.0-0 || ^2.6.0"
783 | },
784 | "peerDependenciesMeta": {
785 | "@vue/composition-api": {
786 | "optional": true
787 | }
788 | }
789 | },
790 | "node_modules/@vueuse/integrations": {
791 | "version": "10.5.0",
792 | "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.5.0.tgz",
793 | "integrity": "sha512-fm5sXLCK0Ww3rRnzqnCQRmfjDURaI4xMsx+T+cec0ngQqHx/JgUtm8G0vRjwtonIeTBsH1Q8L3SucE+7K7upJQ==",
794 | "dev": true,
795 | "dependencies": {
796 | "@vueuse/core": "10.5.0",
797 | "@vueuse/shared": "10.5.0",
798 | "vue-demi": ">=0.14.6"
799 | },
800 | "funding": {
801 | "url": "https://github.com/sponsors/antfu"
802 | },
803 | "peerDependencies": {
804 | "async-validator": "*",
805 | "axios": "*",
806 | "change-case": "*",
807 | "drauu": "*",
808 | "focus-trap": "*",
809 | "fuse.js": "*",
810 | "idb-keyval": "*",
811 | "jwt-decode": "*",
812 | "nprogress": "*",
813 | "qrcode": "*",
814 | "sortablejs": "*",
815 | "universal-cookie": "*"
816 | },
817 | "peerDependenciesMeta": {
818 | "async-validator": {
819 | "optional": true
820 | },
821 | "axios": {
822 | "optional": true
823 | },
824 | "change-case": {
825 | "optional": true
826 | },
827 | "drauu": {
828 | "optional": true
829 | },
830 | "focus-trap": {
831 | "optional": true
832 | },
833 | "fuse.js": {
834 | "optional": true
835 | },
836 | "idb-keyval": {
837 | "optional": true
838 | },
839 | "jwt-decode": {
840 | "optional": true
841 | },
842 | "nprogress": {
843 | "optional": true
844 | },
845 | "qrcode": {
846 | "optional": true
847 | },
848 | "sortablejs": {
849 | "optional": true
850 | },
851 | "universal-cookie": {
852 | "optional": true
853 | }
854 | }
855 | },
856 | "node_modules/@vueuse/integrations/node_modules/vue-demi": {
857 | "version": "0.14.6",
858 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
859 | "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
860 | "dev": true,
861 | "hasInstallScript": true,
862 | "bin": {
863 | "vue-demi-fix": "bin/vue-demi-fix.js",
864 | "vue-demi-switch": "bin/vue-demi-switch.js"
865 | },
866 | "engines": {
867 | "node": ">=12"
868 | },
869 | "funding": {
870 | "url": "https://github.com/sponsors/antfu"
871 | },
872 | "peerDependencies": {
873 | "@vue/composition-api": "^1.0.0-rc.1",
874 | "vue": "^3.0.0-0 || ^2.6.0"
875 | },
876 | "peerDependenciesMeta": {
877 | "@vue/composition-api": {
878 | "optional": true
879 | }
880 | }
881 | },
882 | "node_modules/@vueuse/metadata": {
883 | "version": "10.5.0",
884 | "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.5.0.tgz",
885 | "integrity": "sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==",
886 | "dev": true,
887 | "funding": {
888 | "url": "https://github.com/sponsors/antfu"
889 | }
890 | },
891 | "node_modules/@vueuse/shared": {
892 | "version": "10.5.0",
893 | "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.5.0.tgz",
894 | "integrity": "sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==",
895 | "dev": true,
896 | "dependencies": {
897 | "vue-demi": ">=0.14.6"
898 | },
899 | "funding": {
900 | "url": "https://github.com/sponsors/antfu"
901 | }
902 | },
903 | "node_modules/@vueuse/shared/node_modules/vue-demi": {
904 | "version": "0.14.6",
905 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
906 | "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
907 | "dev": true,
908 | "hasInstallScript": true,
909 | "bin": {
910 | "vue-demi-fix": "bin/vue-demi-fix.js",
911 | "vue-demi-switch": "bin/vue-demi-switch.js"
912 | },
913 | "engines": {
914 | "node": ">=12"
915 | },
916 | "funding": {
917 | "url": "https://github.com/sponsors/antfu"
918 | },
919 | "peerDependencies": {
920 | "@vue/composition-api": "^1.0.0-rc.1",
921 | "vue": "^3.0.0-0 || ^2.6.0"
922 | },
923 | "peerDependenciesMeta": {
924 | "@vue/composition-api": {
925 | "optional": true
926 | }
927 | }
928 | },
929 | "node_modules/algoliasearch": {
930 | "version": "4.20.0",
931 | "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.20.0.tgz",
932 | "integrity": "sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==",
933 | "dev": true,
934 | "dependencies": {
935 | "@algolia/cache-browser-local-storage": "4.20.0",
936 | "@algolia/cache-common": "4.20.0",
937 | "@algolia/cache-in-memory": "4.20.0",
938 | "@algolia/client-account": "4.20.0",
939 | "@algolia/client-analytics": "4.20.0",
940 | "@algolia/client-common": "4.20.0",
941 | "@algolia/client-personalization": "4.20.0",
942 | "@algolia/client-search": "4.20.0",
943 | "@algolia/logger-common": "4.20.0",
944 | "@algolia/logger-console": "4.20.0",
945 | "@algolia/requester-browser-xhr": "4.20.0",
946 | "@algolia/requester-common": "4.20.0",
947 | "@algolia/requester-node-http": "4.20.0",
948 | "@algolia/transporter": "4.20.0"
949 | }
950 | },
951 | "node_modules/ansi-sequence-parser": {
952 | "version": "1.1.1",
953 | "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
954 | "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
955 | "dev": true
956 | },
957 | "node_modules/csstype": {
958 | "version": "3.1.2",
959 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
960 | "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
961 | "dev": true
962 | },
963 | "node_modules/esbuild": {
964 | "version": "0.18.20",
965 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
966 | "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
967 | "dev": true,
968 | "hasInstallScript": true,
969 | "bin": {
970 | "esbuild": "bin/esbuild"
971 | },
972 | "engines": {
973 | "node": ">=12"
974 | },
975 | "optionalDependencies": {
976 | "@esbuild/android-arm": "0.18.20",
977 | "@esbuild/android-arm64": "0.18.20",
978 | "@esbuild/android-x64": "0.18.20",
979 | "@esbuild/darwin-arm64": "0.18.20",
980 | "@esbuild/darwin-x64": "0.18.20",
981 | "@esbuild/freebsd-arm64": "0.18.20",
982 | "@esbuild/freebsd-x64": "0.18.20",
983 | "@esbuild/linux-arm": "0.18.20",
984 | "@esbuild/linux-arm64": "0.18.20",
985 | "@esbuild/linux-ia32": "0.18.20",
986 | "@esbuild/linux-loong64": "0.18.20",
987 | "@esbuild/linux-mips64el": "0.18.20",
988 | "@esbuild/linux-ppc64": "0.18.20",
989 | "@esbuild/linux-riscv64": "0.18.20",
990 | "@esbuild/linux-s390x": "0.18.20",
991 | "@esbuild/linux-x64": "0.18.20",
992 | "@esbuild/netbsd-x64": "0.18.20",
993 | "@esbuild/openbsd-x64": "0.18.20",
994 | "@esbuild/sunos-x64": "0.18.20",
995 | "@esbuild/win32-arm64": "0.18.20",
996 | "@esbuild/win32-ia32": "0.18.20",
997 | "@esbuild/win32-x64": "0.18.20"
998 | }
999 | },
1000 | "node_modules/estree-walker": {
1001 | "version": "2.0.2",
1002 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1003 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
1004 | "dev": true
1005 | },
1006 | "node_modules/focus-trap": {
1007 | "version": "7.5.4",
1008 | "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz",
1009 | "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==",
1010 | "dev": true,
1011 | "dependencies": {
1012 | "tabbable": "^6.2.0"
1013 | }
1014 | },
1015 | "node_modules/fsevents": {
1016 | "version": "2.3.3",
1017 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1018 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1019 | "dev": true,
1020 | "hasInstallScript": true,
1021 | "optional": true,
1022 | "os": [
1023 | "darwin"
1024 | ],
1025 | "engines": {
1026 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1027 | }
1028 | },
1029 | "node_modules/jsonc-parser": {
1030 | "version": "3.2.0",
1031 | "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
1032 | "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
1033 | "dev": true
1034 | },
1035 | "node_modules/magic-string": {
1036 | "version": "0.30.5",
1037 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
1038 | "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
1039 | "dev": true,
1040 | "dependencies": {
1041 | "@jridgewell/sourcemap-codec": "^1.4.15"
1042 | },
1043 | "engines": {
1044 | "node": ">=12"
1045 | }
1046 | },
1047 | "node_modules/mark.js": {
1048 | "version": "8.11.1",
1049 | "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
1050 | "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==",
1051 | "dev": true
1052 | },
1053 | "node_modules/minisearch": {
1054 | "version": "6.1.0",
1055 | "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.1.0.tgz",
1056 | "integrity": "sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==",
1057 | "dev": true
1058 | },
1059 | "node_modules/nanoid": {
1060 | "version": "3.3.6",
1061 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
1062 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
1063 | "dev": true,
1064 | "funding": [
1065 | {
1066 | "type": "github",
1067 | "url": "https://github.com/sponsors/ai"
1068 | }
1069 | ],
1070 | "bin": {
1071 | "nanoid": "bin/nanoid.cjs"
1072 | },
1073 | "engines": {
1074 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1075 | }
1076 | },
1077 | "node_modules/picocolors": {
1078 | "version": "1.0.0",
1079 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1080 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1081 | "dev": true
1082 | },
1083 | "node_modules/postcss": {
1084 | "version": "8.4.31",
1085 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
1086 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
1087 | "dev": true,
1088 | "funding": [
1089 | {
1090 | "type": "opencollective",
1091 | "url": "https://opencollective.com/postcss/"
1092 | },
1093 | {
1094 | "type": "tidelift",
1095 | "url": "https://tidelift.com/funding/github/npm/postcss"
1096 | },
1097 | {
1098 | "type": "github",
1099 | "url": "https://github.com/sponsors/ai"
1100 | }
1101 | ],
1102 | "dependencies": {
1103 | "nanoid": "^3.3.6",
1104 | "picocolors": "^1.0.0",
1105 | "source-map-js": "^1.0.2"
1106 | },
1107 | "engines": {
1108 | "node": "^10 || ^12 || >=14"
1109 | }
1110 | },
1111 | "node_modules/preact": {
1112 | "version": "10.18.1",
1113 | "resolved": "https://registry.npmjs.org/preact/-/preact-10.18.1.tgz",
1114 | "integrity": "sha512-mKUD7RRkQQM6s7Rkmi7IFkoEHjuFqRQUaXamO61E6Nn7vqF/bo7EZCmSyrUnp2UWHw0O7XjZ2eeXis+m7tf4lg==",
1115 | "dev": true,
1116 | "funding": {
1117 | "type": "opencollective",
1118 | "url": "https://opencollective.com/preact"
1119 | }
1120 | },
1121 | "node_modules/rollup": {
1122 | "version": "3.29.4",
1123 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
1124 | "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
1125 | "dev": true,
1126 | "bin": {
1127 | "rollup": "dist/bin/rollup"
1128 | },
1129 | "engines": {
1130 | "node": ">=14.18.0",
1131 | "npm": ">=8.0.0"
1132 | },
1133 | "optionalDependencies": {
1134 | "fsevents": "~2.3.2"
1135 | }
1136 | },
1137 | "node_modules/search-insights": {
1138 | "version": "2.9.0",
1139 | "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.9.0.tgz",
1140 | "integrity": "sha512-bkWW9nIHOFkLwjQ1xqVaMbjjO5vhP26ERsH9Y3pKr8imthofEFIxlnOabkmGcw6ksRj9jWidcI65vvjJH/nTGg==",
1141 | "dev": true,
1142 | "peer": true
1143 | },
1144 | "node_modules/shiki": {
1145 | "version": "0.14.5",
1146 | "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz",
1147 | "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==",
1148 | "dev": true,
1149 | "dependencies": {
1150 | "ansi-sequence-parser": "^1.1.0",
1151 | "jsonc-parser": "^3.2.0",
1152 | "vscode-oniguruma": "^1.7.0",
1153 | "vscode-textmate": "^8.0.0"
1154 | }
1155 | },
1156 | "node_modules/source-map-js": {
1157 | "version": "1.0.2",
1158 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1159 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1160 | "dev": true,
1161 | "engines": {
1162 | "node": ">=0.10.0"
1163 | }
1164 | },
1165 | "node_modules/tabbable": {
1166 | "version": "6.2.0",
1167 | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
1168 | "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
1169 | "dev": true
1170 | },
1171 | "node_modules/vite": {
1172 | "version": "4.5.0",
1173 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
1174 | "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
1175 | "dev": true,
1176 | "dependencies": {
1177 | "esbuild": "^0.18.10",
1178 | "postcss": "^8.4.27",
1179 | "rollup": "^3.27.1"
1180 | },
1181 | "bin": {
1182 | "vite": "bin/vite.js"
1183 | },
1184 | "engines": {
1185 | "node": "^14.18.0 || >=16.0.0"
1186 | },
1187 | "funding": {
1188 | "url": "https://github.com/vitejs/vite?sponsor=1"
1189 | },
1190 | "optionalDependencies": {
1191 | "fsevents": "~2.3.2"
1192 | },
1193 | "peerDependencies": {
1194 | "@types/node": ">= 14",
1195 | "less": "*",
1196 | "lightningcss": "^1.21.0",
1197 | "sass": "*",
1198 | "stylus": "*",
1199 | "sugarss": "*",
1200 | "terser": "^5.4.0"
1201 | },
1202 | "peerDependenciesMeta": {
1203 | "@types/node": {
1204 | "optional": true
1205 | },
1206 | "less": {
1207 | "optional": true
1208 | },
1209 | "lightningcss": {
1210 | "optional": true
1211 | },
1212 | "sass": {
1213 | "optional": true
1214 | },
1215 | "stylus": {
1216 | "optional": true
1217 | },
1218 | "sugarss": {
1219 | "optional": true
1220 | },
1221 | "terser": {
1222 | "optional": true
1223 | }
1224 | }
1225 | },
1226 | "node_modules/vitepress": {
1227 | "version": "1.0.0-rc.22",
1228 | "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-rc.22.tgz",
1229 | "integrity": "sha512-n7le5iikCFgWMuX7sKfzDGJGlrsYQ5trG3S97BghNz2alOTr4Xp+GrB6ShwogUTX9gNgeNmrACjokhW55LNeBA==",
1230 | "dev": true,
1231 | "dependencies": {
1232 | "@docsearch/css": "^3.5.2",
1233 | "@docsearch/js": "^3.5.2",
1234 | "@types/markdown-it": "^13.0.2",
1235 | "@vue/devtools-api": "^6.5.1",
1236 | "@vueuse/core": "^10.5.0",
1237 | "@vueuse/integrations": "^10.5.0",
1238 | "focus-trap": "^7.5.4",
1239 | "mark.js": "8.11.1",
1240 | "minisearch": "^6.1.0",
1241 | "shiki": "^0.14.5",
1242 | "vite": "^4.4.11",
1243 | "vue": "^3.3.4"
1244 | },
1245 | "bin": {
1246 | "vitepress": "bin/vitepress.js"
1247 | },
1248 | "peerDependencies": {
1249 | "markdown-it-mathjax3": "^4.3.2",
1250 | "postcss": "^8.4.31"
1251 | },
1252 | "peerDependenciesMeta": {
1253 | "markdown-it-mathjax3": {
1254 | "optional": true
1255 | },
1256 | "postcss": {
1257 | "optional": true
1258 | }
1259 | }
1260 | },
1261 | "node_modules/vscode-oniguruma": {
1262 | "version": "1.7.0",
1263 | "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
1264 | "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
1265 | "dev": true
1266 | },
1267 | "node_modules/vscode-textmate": {
1268 | "version": "8.0.0",
1269 | "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
1270 | "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
1271 | "dev": true
1272 | },
1273 | "node_modules/vue": {
1274 | "version": "3.3.4",
1275 | "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
1276 | "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
1277 | "dev": true,
1278 | "dependencies": {
1279 | "@vue/compiler-dom": "3.3.4",
1280 | "@vue/compiler-sfc": "3.3.4",
1281 | "@vue/runtime-dom": "3.3.4",
1282 | "@vue/server-renderer": "3.3.4",
1283 | "@vue/shared": "3.3.4"
1284 | }
1285 | }
1286 | }
1287 | }
1288 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "vitepress": "^1.0.0-rc.13"
4 | },
5 | "scripts": {
6 | "docs:dev": "vitepress dev docs",
7 | "docs:build": "vitepress build docs",
8 | "docs:preview": "vitepress preview docs"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Bases/BaseSpellNumber.php:
--------------------------------------------------------------------------------
1 | result();
23 |
24 | return new static($value, $type);
25 | }
26 |
27 | /**
28 | * Creates an instance of the child class with the provided integer value for conversion.
29 | *
30 | * @param int $value The integer value to convert to words.
31 | *
32 | * @throws SpellNumberExceptions When the Intl extension is not available or the value is not a valid integer.
33 | *
34 | * @return static An instance of the child class.
35 | */
36 | public static function integer($value)
37 | {
38 | SpellNumberValidator::check('integer', $value)->result();
39 |
40 | return new static($value, 'integer');
41 | }
42 |
43 | /**
44 | * Creates an instance of the child class with the provided float value for conversion.
45 | *
46 | * @param float $value The float value to convert to words.
47 | *
48 | * @throws SpellNumberExceptions When the Intl extension is not available or the value is not a valid float.
49 | *
50 | * @return static An instance of the child class.
51 | */
52 | public static function float($value)
53 | {
54 | SpellNumberValidator::check('double', $value)->result();
55 |
56 | return new static($value, 'double');
57 | }
58 |
59 | /**
60 | * Returns the list of available premises according to PHP.
61 | *
62 | * @return array An array containing all locales.
63 | */
64 | public static function getAllLocales()
65 | {
66 | try {
67 | $availableLocales = \ResourceBundle::getLocales('');
68 |
69 | return $availableLocales;
70 | } catch (\Throwable $th) {
71 | return array_keys(Langs::LOCALES_AVAILABLE);
72 | }
73 | }
74 |
75 | /**
76 | * Retrieves a list of all available locales supported by the NumberFormatter class.
77 | *
78 | * @return array An array containing all available locales.
79 | */
80 | public static function getAvailableLocales()
81 | {
82 | return array_keys(Langs::LOCALES_AVAILABLE);
83 | }
84 |
85 | /**
86 | * Retrieves a list of all available TimeZones by the NumberFormatter class.
87 | *
88 | * @return array An array containing all available locales.
89 | */
90 | public static function getAvailableLanguages()
91 | {
92 | return Langs::LOCALES_AVAILABLE;
93 | }
94 |
95 | /**
96 | * DEPRECATED - Delete Method Soon
97 | * Retrieves a list of all available locales supported by the NumberFormatter class.
98 | *
99 | * @return array An array containing all available locales.
100 | */
101 | public static function getLocales()
102 | {
103 | return self::getAvailableLocales();
104 | }
105 |
106 | /**
107 | * DEPRECATED - Delete Method Soon
108 | * Retrieves a list of all available TimeZones by the NumberFormatter class.
109 | *
110 | * @return array An array containing all available locales.
111 | */
112 | public static function getLanguages()
113 | {
114 | return self::getAvailableLanguages();
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/Bases/BaseSpellNumberValidator.php:
--------------------------------------------------------------------------------
1 | method = $data['method'] ?? null;
25 | $this->type = $data['type'] ?? null;
26 | $this->value = $data['value'] ?? null;
27 | $this->words = $data['words'] ?? null;
28 | $this->lang = $data['lang'] ?? null;
29 | $this->locale = $data['locale'] ?? null;
30 | $this->mode = $data['mode'] ?? null;
31 | $this->currency = $data['currency'] ?? null;
32 | $this->fraction = $data['fraction'] ?? null;
33 | }
34 |
35 | /**
36 | * Get the method associated with the response.
37 | *
38 | * @return string The method name.
39 | */
40 | public function getMethod()
41 | {
42 | return $this->method;
43 | }
44 |
45 | /**
46 | * Get the type associated with the response.
47 | *
48 | * @return string The response type.
49 | */
50 | public function getType()
51 | {
52 | return $this->type;
53 | }
54 |
55 | /**
56 | * Get the value associated with the response.
57 | *
58 | * @return mixed The response value.
59 | */
60 | public function getValue()
61 | {
62 | return $this->value;
63 | }
64 |
65 | /**
66 | * Get the words associated with the response.
67 | *
68 | * @return string The response words.
69 | */
70 | public function getWords()
71 | {
72 | return $this->words;
73 | }
74 |
75 | /**
76 | * Get the language associated with the response.
77 | *
78 | * @return string The response language.
79 | */
80 | public function getLang()
81 | {
82 | return $this->lang;
83 | }
84 |
85 | /**
86 | * Get the locale associated with the response.
87 | *
88 | * @return string The response locale.
89 | */
90 | public function getLocale()
91 | {
92 | return $this->locale;
93 | }
94 |
95 | /**
96 | * Get the currency associated with the response.
97 | *
98 | * @return string The response currency.
99 | */
100 | public function getCurrency()
101 | {
102 | return $this->currency;
103 | }
104 |
105 | /**
106 | * Get the fraction associated with the response.
107 | *
108 | * @return string The response fraction.
109 | */
110 | public function getFraction()
111 | {
112 | return $this->fraction;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/Exceptions/SpellNumberExceptions.php:
--------------------------------------------------------------------------------
1 | 'German', // German from Germany.
18 | 'en' => 'English', // English from the United States.
19 | 'es' => 'Spanish', // Spanish from Spain.
20 | 'fa' => 'Farsi', // Farsi from Iran.
21 | 'fr' => 'French', // French from France.
22 | 'hi' => 'Hindi', // Hindi from India.
23 | 'it' => 'Italian', // Italian from Italy.
24 | 'pl' => 'Polish', // Polish from Poland.
25 | 'pt' => 'Portuguese', // Portuguese from Portugal.
26 | 'ro' => 'Romanian', // Romanian from Romania.
27 | 'vi' => 'Vietnamese', // Vietnamese from Vietnam.
28 | ];
29 |
30 | /**
31 | * Array containing connectors for each language.
32 | *
33 | * @var array
34 | */
35 | public const LOCALES_CONNECTORS = [
36 | 'de' => 'und', // German from Germany: "und"
37 | 'en' => 'and', // English from the United States: "and"
38 | 'es' => 'con', // Spanish from Spain: "con"
39 | 'fa' => 'ممیز', // Farsi from Iran: "ممیز"
40 | 'fr' => 'et', // French from France: "et"
41 | 'hi' => 'और', // Hindi from India: "और"
42 | 'it' => 'con', // Italian from Italy: "con"
43 | 'pl' => 'i', // Polish from Poland: "i"
44 | 'pt' => 'com', // Portuguese from Portugal: "com"
45 | 'ro' => 'cu', // Romanian from Romania: "cu"
46 | 'vi' => 'và', // Vietnamese from Vietnam: "và"
47 | ];
48 |
49 | /**
50 | * Array containing connectors for each language used when representing money.
51 | *
52 | * @var array
53 | */
54 | public const LOCALES_CONNECTORS_MONEY = [
55 | 'de' => 'von', // German frm Germany: "von"
56 | 'en' => 'of', // English from the United States: "of"
57 | 'es' => 'de', // Spanish from Spain: "de"
58 | 'fa' => 'از', // Farsi from Iran: "از"
59 | 'fr' => 'de', // French from France: "de"
60 | 'hi' => 'का', // Hindi from India: "का"
61 | 'it' => 'di', // Italian from Italy: "di"
62 | 'pl' => 'i', // Polish from Poland: "i"
63 | 'pt' => 'de', // Portuguese from Portugal: "de"
64 | 'ro' => 'de', // Romanian from Romania: "de"
65 | 'vi' => 'của', // Vietnamese from Vietnam: "của"
66 | ];
67 | }
68 |
--------------------------------------------------------------------------------
/src/Langs/Replaces.php:
--------------------------------------------------------------------------------
1 | toMoney()
13 | * The primary value must be there, that is, "es" instead of "es_ES" or similar.
14 | */
15 | public const TO_MONEY = [
16 | 'de' => [
17 | // 'illion' => 'illion Von',
18 | ],
19 | 'en' => [
20 | 'illion' => 'illion of',
21 | ],
22 | 'es' => [
23 | 'veintiuno' => 'veintiún',
24 | 'treinta Y Uno' => 'treintaiún',
25 | 'cuarenta y uno' => 'cuarentaiún',
26 | 'cincuenta y uno' => 'cincuentaiún',
27 | 'sesenta y uno' => 'sesentaiún',
28 | 'setenta y uno' => 'setentaiún',
29 | 'ochenta y uno' => 'ochentaiún',
30 | 'noventa y uno' => 'noventaiún',
31 | 'ciento uno' => 'ciento un',
32 | 'doscientos uno' => 'doscientos un',
33 | 'trescientos uno' => 'trescientos un',
34 | 'cuatrocientos uno' => 'cuatrocientos un',
35 | 'quinientos uno' => 'quinientos un',
36 | 'seiscientos uno' => 'seiscientos un',
37 | 'setecientos uno' => 'setecientos un',
38 | 'ochocientos uno' => 'ochocientos un',
39 | 'novecientos uno' => 'novecientos un',
40 | 'mil uno' => 'mil un',
41 | 'uno millón' => 'un millón',
42 | 'illón' => 'illón De',
43 | 'illones' => 'illones De',
44 | 'uno pesos' => 'un peso',
45 | 'uno soles' => 'un sol',
46 | 'uno euros' => 'un euro',
47 | 'uno bolívares' => 'un bolívar',
48 | 'uno bolivares' => 'un bolívar',
49 | 'uno quetzales' => 'un quetzal',
50 | 'uno lempiras' => 'un lempira',
51 | 'uno córdobas' => 'un córdoba',
52 | 'uno cordobas' => 'un córdoba',
53 | 'uno colónes' => 'un colón',
54 | 'uno colones' => 'un colón',
55 | 'uno balboas' => 'un balboa',
56 | 'uno centavos' => 'un centavo',
57 | 'uno céntimos' => 'un céntimo',
58 | 'uno centimos' => 'un céntimo',
59 | 'uno centimo' => 'un céntimo',
60 | ],
61 | 'fa' => [
62 | 'ilion' => 'میلیون و',
63 | ],
64 | 'fr' => [
65 | 'illion' => 'illion de',
66 | 'illions' => 'illions de',
67 | ],
68 | 'hi' => [
69 | //...
70 | ],
71 | 'it' => [
72 | 'ilione' => 'ilione di',
73 | 'ilioni' => 'ilioni di',
74 | ],
75 | 'pl' => [
76 | //...
77 | ],
78 | 'pt' => [
79 | 'ilhão' => 'ilhão de',
80 | 'ilhões' => 'ilhões de',
81 | ],
82 | 'ro' => [
83 | 'ilion' => 'ilion de',
84 | 'ilioane' => 'ilioane de',
85 | ],
86 | 'vi' => [
87 | 'illion' => 'illion của',
88 | ],
89 | ];
90 |
91 | /**
92 | * ->toLetters()
93 | * The primary value must be there, that is, "es" instead of "es_ES" or similar.
94 | */
95 | public const TO_LETTERS = [
96 | 'de' => [
97 | //...
98 | ],
99 | 'en' => [
100 | //...
101 | ],
102 | 'es' => [
103 | //...
104 | ],
105 | 'fa' => [
106 | //...
107 | ],
108 | 'fr' => [
109 | //...
110 | ],
111 | 'hi' => [
112 | //...
113 | ],
114 | 'it' => [
115 | //...
116 | ],
117 | 'pl' => [
118 | //...
119 | ],
120 | 'pt' => [
121 | //...
122 | ],
123 | 'ro' => [
124 | //...
125 | ],
126 | 'vi' => [
127 | //...
128 | ],
129 | ];
130 |
131 | /**
132 | * ->toOrdinal()
133 | * The primary value must be there, that is, "es" instead of "es_ES" or similar.
134 | */
135 | public const TO_ORDINAL = [
136 | 'de' => [
137 | //...
138 | ],
139 | 'en' => [
140 | //...
141 | ],
142 | 'es' => [
143 | //...
144 | ],
145 | 'fa' => [
146 | //...
147 | ],
148 | 'fr' => [
149 | //...
150 | ],
151 | 'hi' => [
152 | //...
153 | ],
154 | 'it' => [
155 | //...
156 | ],
157 | 'pl' => [
158 | //...
159 | ],
160 | 'pt' => [
161 | //...
162 | ],
163 | 'ro' => [
164 | //...
165 | ],
166 | 'vi' => [
167 | //...
168 | ],
169 | ];
170 | }
171 |
--------------------------------------------------------------------------------
/src/Miscellaneous/Utilities.php:
--------------------------------------------------------------------------------
1 | 1,
164 | '1' => 10,
165 | '02' => 2,
166 | '2' => 20,
167 | '03' => 3,
168 | '3' => 30,
169 | '04' => 4,
170 | '4' => 40,
171 | '05' => 5,
172 | '5' => 50,
173 | '06' => 6,
174 | '6' => 60,
175 | '07' => 7,
176 | '7' => 70,
177 | '08' => 8,
178 | '8' => 80,
179 | '09' => 9,
180 | '9' => 90,
181 | default => $value,
182 | };
183 |
184 | return $result;
185 | }
186 |
187 | /**
188 | * Extracts the main value of the "Locale" example "es_MX" extracts "es".
189 | *
190 | * @param mixed $string
191 | *
192 | * @return string
193 | */
194 | public static function extractPrimaryLocale($string)
195 | {
196 | return mb_strtolower(substr($string, 0, 2));
197 | }
198 |
199 | /**
200 | * Determine the ordinal text mode based on the provided value.
201 | *
202 | * @param string|null $value The value indicating the ordinal text mode.
203 | *
204 | * @return string The corresponding rule for ordinal text formatting.
205 | */
206 | public static function textOrdinalMode(?string $value)
207 | {
208 | return match ($value) {
209 | 'default' => '%spellout-ordinal',
210 | 'male' => '%spellout-ordinal-masculine',
211 | 'female' => '%spellout-ordinal-feminine',
212 | 'masculine' => '%spellout-ordinal-masculine',
213 | 'feminine' => '%spellout-ordinal-feminine',
214 | '%spellout-ordinal' => '%spellout-ordinal',
215 | '%spellout-ordinal-masculine' => '%spellout-ordinal-masculine',
216 | '%spellout-ordinal-feminine' => '%spellout-ordinal-feminine',
217 | 'ordinal' => '%spellout-ordinal',
218 | 'ordinal-masculine' => '%spellout-ordinal-masculine',
219 | 'ordinal-feminine' => '%spellout-ordinal-feminine',
220 | default => '%spellout-ordinal',
221 | };
222 | }
223 |
224 | /**
225 | * Determine the human-readable ordinal text mode based on the provided value.
226 | *
227 | * @param string|null $value The value indicating the ordinal text mode.
228 | *
229 | * @return string The corresponding human-readable ordinal text mode.
230 | */
231 | public static function textOrdinalModeHuman(?string $value)
232 | {
233 | return match ($value) {
234 | '%spellout-ordinal-masculine' => 'male',
235 | '%spellout-ordinal-feminine' => 'female',
236 | '%spellout-ordinal' => 'default',
237 | };
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/src/Miscellaneous/Words.php:
--------------------------------------------------------------------------------
1 | $replace) {
29 | $search = mb_strtolower($search);
30 | $replace = mb_strtolower($replace);
31 | $value = str_replace($search, $replace, $value);
32 | }
33 |
34 | // Return the adjusted text.
35 | return $value;
36 | }
37 |
38 | /**
39 | * Perform replacements in the given text based on the language and current currency from config file.
40 | *
41 | * @param string $value The original text string.
42 | * @param string $locale The language of the text.
43 | *
44 | * @return string The adjusted text with the replacements performed.
45 | */
46 | public static function replaceFromConfig(string $value, string $locale)
47 | {
48 | // Primary Locale
49 | $locale = Utilities::extractPrimaryLocale($locale);
50 |
51 | //Value
52 | $value = mb_strtolower($value);
53 |
54 | //From Config.
55 | $replacesLocaleConfig = config("spell-number.replacements.$locale") ?? [];
56 | foreach ($replacesLocaleConfig as $search => $replace) {
57 | $search = mb_strtolower($search);
58 | $replace = mb_strtolower($replace);
59 | $value = str_replace($search, $replace, $value);
60 | }
61 |
62 | // Return the adjusted text.
63 | return $value;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Providers/SpellNumberProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
17 | __DIR__.'/../../config/spell-number.php' => config_path('spell-number.php'),
18 | ], 'config');
19 | }
20 |
21 | /**
22 | * Register any package services.
23 | *
24 | * @return void
25 | */
26 | public function register(): void
27 | {
28 | // Register any package-specific services here
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/SpellNumber.php:
--------------------------------------------------------------------------------
1 | value = $value;
49 | $this->type = $type;
50 | $this->locale = config('spell-number.default.lang') ?? config('spell-number.default.locale') ?? Langs::getLocaleLaravel();
51 | $this->currency = config('spell-number.default.currency') ?? 'dollars';
52 | $this->fraction = config('spell-number.default.fraction') ?? 'cents';
53 | }
54 |
55 | /**
56 | * Set the locale for the conversion.
57 | *
58 | * @param string $locale The locale to use for the conversion.
59 | *
60 | * @throws SpellNumberExceptions If the provided locale is not valid.
61 | *
62 | * @return SpellNumber The SpellNumber instance with the updated locale.
63 | */
64 | public function locale(string $locale, ?bool $specific_locale = null)
65 | {
66 | $valueConfig = config('spell-number.default.specific_locale');
67 |
68 | $specific_locale = $specific_locale ?? $valueConfig ?? false;
69 |
70 | if ($specific_locale === false) {
71 | if (!Utilities::isValidLocale($locale)) {
72 | throw SpellNumberExceptions::create('The provided value is not valid. To view the available options, you can use the SpellNumber::getAvailableLocales() method, or you can pass the SpellNumber::SPECIFIC_LOCALE constant as the second parameter to enable specific or customized usage.');
73 | }
74 | }
75 |
76 | $this->locale = $locale;
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * Set the currency for the conversion.
83 | *
84 | * @param string $currency The currency to use for the conversion.
85 | *
86 | * @return SpellNumber The SpellNumber instance with the updated currency.
87 | */
88 | public function currency(string $currency)
89 | {
90 | $this->currency = $currency;
91 |
92 | return $this;
93 | }
94 |
95 | /**
96 | * Set the fraction for the conversion.
97 | *
98 | * @param string $fraction The fraction to use for the conversion.
99 | *
100 | * @return SpellNumber The SpellNumber instance with the updated fraction.
101 | */
102 | public function fraction(string $fraction)
103 | {
104 | $this->fraction = $fraction;
105 |
106 | return $this;
107 | }
108 |
109 | /**
110 | * Convert the numeric value to words.
111 | *
112 | * @return string The textual representation of the numeric value.
113 | */
114 | public function toLetters()
115 | {
116 | $callback = config('spell-number.callback_output');
117 |
118 | if (!empty($callback) && is_callable($callback)) {
119 | $words = ($this->type == 'integer') ? $this->integerToLetters() : $this->doubleToLetters();
120 |
121 | return $callback(new DataResponse([
122 | 'method' => 'toLetters',
123 | 'type' => $this->type,
124 | 'value' => $this->value,
125 | 'words' => $words,
126 | 'lang' => Utilities::extractPrimaryLocale($this->locale),
127 | 'locale' => $this->locale,
128 | 'currency' => null,
129 | 'fraction' => null,
130 | ]));
131 | }
132 |
133 | return ($this->type == 'integer') ? $this->integerToLetters() : $this->doubleToLetters();
134 | }
135 |
136 | /**
137 | * Convert the numeric value to a money representation.
138 | *
139 | * @return string The textual representation of the money value.
140 | */
141 | public function toMoney()
142 | {
143 | $callback = config('spell-number.callback_output');
144 |
145 | if (!empty($callback) && is_callable($callback)) {
146 | $words = ($this->type == 'integer') ? $this->integerToMoney() : $this->doubleToMoney();
147 |
148 | return $callback(new DataResponse([
149 | 'method' => 'toMoney',
150 | 'type' => $this->type,
151 | 'value' => $this->value,
152 | 'words' => $words,
153 | 'lang' => Utilities::extractPrimaryLocale($this->locale),
154 | 'locale' => $this->locale,
155 | 'currency' => $this->currency,
156 | 'fraction' => $this->fraction,
157 | ]));
158 | }
159 |
160 | return ($this->type == 'integer') ? $this->integerToMoney() : $this->doubleToMoney();
161 | }
162 |
163 | /**
164 | * Convert the numeric value to ordinal representation.
165 | *
166 | * @return string The textual representation of the ordinal value.
167 | */
168 | public function toOrdinal(?string $attr = null)
169 | {
170 | $valueConfig = config('spell-number.default.ordinal_output');
171 |
172 | $attr = Utilities::textOrdinalMode($attr ?? $valueConfig);
173 |
174 | $callback = config('spell-number.callback_output');
175 |
176 | if (!empty($callback) && is_callable($callback)) {
177 | $words = $this->integerToOrdinal($attr);
178 |
179 | return $callback(new DataResponse([
180 | 'method' => 'toOrdinal',
181 | 'type' => $this->type,
182 | 'value' => $this->value,
183 | 'words' => $words,
184 | 'lang' => Utilities::extractPrimaryLocale($this->locale),
185 | 'locale' => $this->locale,
186 | 'mode' => Utilities::textOrdinalModeHuman($attr),
187 | ]));
188 | }
189 |
190 | return $this->integerToOrdinal($attr);
191 | }
192 |
193 | /**
194 | * Convert the integer numeric value to its ordinal textual representation.
195 | *
196 | * @return string The textual representation of the ordinal value.
197 | */
198 | private function integerToOrdinal($attr)
199 | {
200 | if ($this->type == 'double') {
201 | throw SpellNumberExceptions::create('To convert to ordinal numbers, an integer value is required as input');
202 | }
203 |
204 | $formatter = NumberFormatterWrapper::format($this->value, $this->locale, true, $attr);
205 | $formatter = Words::replaceLocale($formatter, $this->locale, self::TO_ORDINAL);
206 |
207 | return Words::replaceFromConfig($formatter, $this->locale);
208 | }
209 |
210 | /**
211 | * Convert the integer numeric value to its textual representation.
212 | *
213 | * @return string The textual representation of the integer numeric value.
214 | */
215 | private function integerToLetters()
216 | {
217 | $formatter = NumberFormatterWrapper::format($this->value, $this->locale);
218 | $formatter = Words::replaceLocale($formatter, $this->locale, self::TO_LETTERS);
219 |
220 | return Words::replaceFromConfig($formatter, $this->locale);
221 | }
222 |
223 | /**
224 | * Convert the double numeric value to its textual representation.
225 | *
226 | * @return string The textual representation of the double numeric value.
227 | */
228 | private function doubleToLetters()
229 | {
230 | $parts = explode('.', $this->value);
231 |
232 | if (!array_key_exists(1, $parts)) {
233 | return $this->integerToLetters();
234 | }
235 |
236 | $parts[1] = Utilities::decimal($parts[1]);
237 |
238 | $letters1 = NumberFormatterWrapper::format($parts[0], $this->locale);
239 | $letters2 = NumberFormatterWrapper::format($parts[1], $this->locale);
240 |
241 | $output = sprintf('%s %s %s', $letters1, Utilities::connector($this->locale), $letters2);
242 | $output = Words::replaceLocale($output, $this->locale, self::TO_LETTERS);
243 |
244 | return Words::replaceFromConfig($output, $this->locale);
245 | }
246 |
247 | /**
248 | * Convert the integer numeric value to its money representation.
249 | *
250 | * @return string The money representation of the integer numeric value.
251 | */
252 | private function integerToMoney()
253 | {
254 | $letters = NumberFormatterWrapper::format($this->value, $this->locale).' '.$this->currency;
255 | $letters = Words::replaceLocale($letters, $this->locale, self::TO_MONEY);
256 |
257 | return Words::replaceFromConfig($letters, $this->locale);
258 | }
259 |
260 | /**
261 | * Convert the double numeric value to its money representation.
262 | *
263 | * @return string The money representation of the double numeric value.
264 | */
265 | private function doubleToMoney()
266 | {
267 | $parts = explode('.', $this->value);
268 |
269 | if (!array_key_exists(1, $parts)) {
270 | return $this->integerToMoney();
271 | }
272 |
273 | $parts[1] = Utilities::decimal($parts[1]);
274 |
275 | $letters1 = NumberFormatterWrapper::format($parts[0], $this->locale).' '.$this->currency;
276 | $letters2 = NumberFormatterWrapper::format($parts[1], $this->locale).' '.$this->fraction;
277 |
278 | $output = $letters1.' '.Utilities::connector($this->locale).' '.$letters2;
279 | $output = Words::replaceLocale($output, $this->locale, self::TO_MONEY);
280 |
281 | return Words::replaceFromConfig($output, $this->locale);
282 | }
283 |
284 | /**
285 | * Perform a spell-related action based on the specified method and optional ordinal mode.
286 | *
287 | * @param string $method The method to perform (TO_LETTERS, TO_MONEY, or TO_ORDINAL).
288 | * @param string|null $modeOrdinal The optional ordinal mode when using TO_ORDINAL.
289 | *
290 | * @throws SpellNumberExceptions When the requested action is invalid.
291 | *
292 | * @return mixed The result of the specified action.
293 | */
294 | private function spell(string $method, ?string $modeOrdinal = null)
295 | {
296 | return match ($method) {
297 | 'TO_LETTERS' => $this->toLetters(),
298 | 'TO_MONEY' => $this->toMoney(),
299 | 'TO_ORDINAL' => $this->toOrdinal($modeOrdinal),
300 | default => throw SpellNumberExceptions::create("The requested action does not exist. The 'spell' method only accepts one of the following three options: SpellNumber::TO_LETTERS, SpellNumber::TO_MONEY, or SpellNumber::TO_ORDINAL."),
301 | };
302 | }
303 | }
304 |
--------------------------------------------------------------------------------
/src/Traits/Accesor.php:
--------------------------------------------------------------------------------
1 | value = $value;
29 |
30 | // Check if the intl extension is installed.
31 | $this->validateExtension();
32 |
33 | // Validate that it is not a scientific notation.
34 | $this->validateScientificConnotation();
35 |
36 | // Execute the appropriate validation based on the type.
37 | match ($type) {
38 | 'mixed' => $this->mixed(),
39 | 'integer' => $this->integer(),
40 | 'double' => $this->float()
41 | };
42 | }
43 |
44 | /**
45 | * Validate when the type is "mixed".
46 | *
47 | * @throws SpellNumberExceptions
48 | *
49 | * @return $this
50 | */
51 | public function mixed()
52 | {
53 | $this->validateNumeric();
54 | $this->validateMaximum();
55 | $this->response = $this->validateType();
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * Validate when the type is "integer".
62 | *
63 | * @throws SpellNumberExceptions
64 | *
65 | * @return $this
66 | */
67 | public function integer()
68 | {
69 | $this->validateInteger();
70 | $this->response = $this->validateMaximum();
71 |
72 | return $this;
73 | }
74 |
75 | /**
76 | * Validate when the type is "float".
77 | *
78 | * @throws SpellNumberExceptions
79 | *
80 | * @return $this
81 | */
82 | public function float()
83 | {
84 | $this->validateString();
85 | $this->response = $this->validateMaximum();
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * Get the result of the validation.
92 | *
93 | * @return mixed The result of the validation.
94 | */
95 | public function result()
96 | {
97 | return $this->response;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Validator/Traits/CommonValidate.php:
--------------------------------------------------------------------------------
1 | value)) {
18 | throw SpellNumberExceptions::create('The entered value exceeds the processable limits of the current version of PHP and has become a Scientific Connotation.');
19 | }
20 |
21 | return true;
22 | }
23 |
24 | /**
25 | * Validate that the "Intl" extension is loaded.
26 | *
27 | * @throws SpellNumberExceptions If the "Intl" extension is not installed or not available.
28 | */
29 | private function validateExtension()
30 | {
31 | if (!Utilities::validateExtension('Intl')) {
32 | throw SpellNumberExceptions::create('The INTL extension is not installed or not available. (https://www.php.net/manual/es/intl.installation.php)');
33 | }
34 |
35 | return true;
36 | }
37 |
38 | /**
39 | * Validate if the value is numeric.
40 | *
41 | * @throws SpellNumberExceptions If the supplied value is not valid (not integer or float).
42 | */
43 | private function validateNumeric()
44 | {
45 | if (!Utilities::isValidNumber($this->value)) {
46 | throw SpellNumberExceptions::create('The provided value is not valid. It must be of type integer or float (double). Additionally, scientific overtones generated when the maximum number available in the current version of PHP is exceeded cannot be processed.');
47 | }
48 |
49 | return true;
50 | }
51 |
52 | /**
53 | * Validate if the value is an integer.
54 | *
55 | * @throws SpellNumberExceptions If the supplied value is not a valid integer.
56 | */
57 | private function validateInteger()
58 | {
59 | if (!Utilities::isValidInteger($this->value)) {
60 | throw SpellNumberExceptions::create('The supplied value is not valid. It must be of type integer.');
61 | }
62 |
63 | return true;
64 | }
65 |
66 | /**
67 | * Validate if the value is a string.
68 | *
69 | * @throws SpellNumberExceptions If the supplied value is not a valid string.
70 | */
71 | private function validateString()
72 | {
73 | if (!Utilities::isValidString($this->value)) {
74 | throw SpellNumberExceptions::create('The supplied value is not valid. It must be of type String.');
75 | }
76 |
77 | return true;
78 | }
79 |
80 | /**
81 | * Validate if the value does not exceed the maximum allowed value.
82 | *
83 | * @throws SpellNumberExceptions If the entered value exceeds the maximum allowed value.
84 | */
85 | private function validateMaximum()
86 | {
87 | if (!Utilities::isNotExceedMax($this->value)) {
88 | throw SpellNumberExceptions::create('The value entered is too large and has been converted to scientific notation which prevents processing.');
89 | }
90 |
91 | return true;
92 | }
93 |
94 | /**
95 | * Validate the type of the value.
96 | *
97 | * @return string Returns "integer" if the value is a valid integer, otherwise "double".
98 | */
99 | private function validateType()
100 | {
101 | return Utilities::isValidInteger($this->value) ? 'integer' : 'double';
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Wrappers/NumberFormatterWrapper.php:
--------------------------------------------------------------------------------
1 | setTextAttribute(NumberFormatter::DEFAULT_RULESET, $attr);
28 | }
29 |
30 | // Format the given numeric value as a spelled-out string.
31 | $value = $numberFormatter->format($value);
32 |
33 | return str_replace(["\u{AD}", "\u{200B}"], '', $value);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/test/SpellNumberTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(SpellNumber::value(100)->locale('en')->toLetters(), 'One Hundred');
13 |
14 | // Spanish locale
15 | $this->assertEquals(SpellNumber::value(100)->locale('es')->toLetters(), 'Cien');
16 |
17 | // Farsi (Persian) locale
18 | $this->assertEquals(SpellNumber::value(100)->locale('fa')->toLetters(), 'صد');
19 |
20 | // Hindi locale
21 | $this->assertEquals(SpellNumber::value(100)->locale('hi')->toLetters(), 'एक सौ');
22 |
23 | // Test conversion of floating-point value to letters in English locale
24 | $this->assertEquals(SpellNumber::value(123456789.12)->locale('en')->toLetters(), 'One Hundred Twenty-Three Million Four Hundred Fifty-Six Thousand Seven Hundred Eighty-Nine And Twelve');
25 |
26 | // Test conversion of integer to letters in English locale
27 | $this->assertEquals(SpellNumber::integer(100)->locale('en')->toLetters(), 'One Hundred');
28 |
29 | // Test conversion of floating-point value to letters in English locale
30 | $this->assertEquals(SpellNumber::float('12345.230')->locale('en')->toLetters(), 'Twelve Thousand Three Hundred Forty-Five And Two Hundred Thirty');
31 | }
32 |
33 | // Test conversion of numerical value to money representation in different locales
34 | public function testToMoney()
35 | {
36 | // English locale with 'Dollars' currency
37 | $this->assertEquals(SpellNumber::value(100)->locale('en')->currency('Dollars')->toMoney(), 'One Hundred Dollars');
38 |
39 | // Spanish locale with 'Pesos' currency
40 | $this->assertEquals(SpellNumber::value(100)->locale('es')->currency('Pesos')->toMoney(), 'Cien Pesos');
41 |
42 | // Hindi locale with 'रूपये' currency
43 | $this->assertEquals(SpellNumber::value(100)->locale('hi')->currency('रूपये')->toMoney(), 'एक सौ रूपये');
44 |
45 | // Test conversion of integer to money representation in Spanish locale
46 | $this->assertEquals(SpellNumber::integer(100)->locale('es')->currency('Pesos')->toMoney(), 'Cien Pesos');
47 |
48 | // Test conversion of floating-point value to money representation in Spanish locale
49 | $this->assertEquals(SpellNumber::float('12345.230')->locale('es')->currency('Pesos')->fraction('Centavos')->toMoney(), 'Doce Mil Trescientos Cuarenta Y Cinco Pesos Con Doscientos Treinta Centavos');
50 | }
51 | }
52 |
--------------------------------------------------------------------------------