diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..aecc3bc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_size = 4 diff --git a/.env.dusk b/.env.dusk new file mode 100644 index 0000000..27d89da --- /dev/null +++ b/.env.dusk @@ -0,0 +1,47 @@ +APP_NAME=Deployer +APP_ENV=dusk +APP_KEY=base64:PrEuajG9mhMu48SDXAKd8xrIMyujCQG+HbDV0U+MjRY= +APP_DEBUG=true +APP_URL=http://127.0.0.1:8000 + +LOG_CHANNEL=stack + +DB_CONNECTION=pgsql +DB_HOST=127.0.0.1 +DB_PORT=5432 +DB_DATABASE=homestead +DB_USERNAME=homestead +DB_PASSWORD=password + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=log +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +SENTRY_LARAVEL_DSN= + +RESPONSE_CACHE_ENABLED=false +RESPONSE_CACHE_DRIVER=redis + +RECAPTCHA_SITE= +RECAPTCHA_SECRET= + +TELESCOPE_ENABLED=false + +DEMO_MODE_ENABLED=false +DEBUGBAR_ENABLED=false +ENABLE_COOKIECONSENT=false diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7036237 --- /dev/null +++ b/.env.example @@ -0,0 +1,56 @@ +APP_NAME=Deployer +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://deployer.test + +LOG_CHANNEL=stack + +DB_CONNECTION=pgsql +DB_HOST=127.0.0.1 +DB_PORT=5432 +DB_DATABASE=deployer +DB_USERNAME=deployer +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=null +MAIL_FROM_NAME="${APP_NAME}" + +SENTRY_LARAVEL_DSN= + +RESPONSE_CACHE_ENABLED=false +RESPONSE_CACHE_DRIVER=redis + +RECAPTCHA_SITE= +RECAPTCHA_SECRET= + +FAKEID_PRIME=1601895473 +FAKEID_INVERSE=1212079313 +FAKEID_RANDOM=360160081 + +GOOGLE_ANALYTICS_TRACKING_KEY=G- +# Optional, used to remove the google analytics cookies that are stored within +# the site domain, only neccesary if you are running the app in a subdomain +# `dev.deployer.io` should use `deployer.io` +# or `deployer.io.test` should use `io.test` +GOOGLE_ANALYTICS_COOKIE_DOMAIN= + +ZENDESK_SUBDOMAIN= +ZENDESK_USERNAME= +ZENDESK_TOKEN= diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..9f03390 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": ["eslint:recommended", "plugin:vue/essential"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly", + "route": true, + "require": true + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "plugins": ["vue"], + "rules": {} +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..967315d --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto +*.css linguist-vendored +*.scss linguist-vendored +*.js linguist-vendored +CHANGELOG.md export-ignore diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..8858ad2 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,30 @@ + + +## Summary + + + + + + + +## Checklist + + + +- [ ] I checked my UI changes against the design and there are no notable differences +- [ ] I checked my UI changes for any responsiveness issues +- [ ] I checked my (code) changes for obvious issues, debug statements and commented code +- [ ] I opened a corresponding card on Clickup for any remaining TODOs in my code +- [ ] I added a short description on how to test this PR _(if necessary)_ +- [ ] Documentation _(if necessary)_ +- [ ] Tests _(if necessary)_ +- [ ] Ready to be merged + + diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..94bd2ec --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,23 @@ +version: 1 + +labels: + - label: "bugfix" + title: "^fix.*" + - label: "feature" + title: "^feat.*" + - label: "build" + title: "^build.*" + - label: "chore" + title: "^chore.*" + - label: "ci" + title: "^ci.*" + - label: "docs" + title: "^docs.*" + - label: "style" + title: "^style.*" + - label: "refactor" + title: "^refactor.*" + - label: "performance" + title: "^perf.*" + - label: "test" + title: "^test.*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e40912a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,207 @@ +name: CI + +on: + push: + branches: + - "master" + - "develop" + pull_request: + types: [ready_for_review, synchronize, opened] + +jobs: + conflicts: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + + - name: Merge Conflict finder + uses: olivernybroe/action-conflict-finder@v4.0 + + analyse: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite, pcov + coverage: pcov + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache/files + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Install Composer dependencies + run: composer install --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + - name: Prepare the application + run: cp .env.example .env && php artisan key:generate + + - name: Run PHPStan + run: composer analyse + + format: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite, pcov + coverage: pcov + + - name: Install + run: composer install --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + - name: Run php-cs-fixer + run: PHP_CS_FIXER_IGNORE_ENV=true composer format + + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: "style: resolve style guide violations" + branch: ${{ github.head_ref }} + + unit: + needs: [conflicts, analyse, format] + + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:12 + env: + POSTGRES_DB: deployer + POSTGRES_USER: deployer + POSTGRES_PASSWORD: password + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.1" + extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite, pcov + coverage: pcov + + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: ~/.composer/cache/files + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Install Composer dependencies + run: composer install --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + - name: Prepare the application + run: cp .env.example .env && php artisan key:generate + + - name: Clear Config + run: php artisan config:clear && php artisan route:clear + + - name: Run Tests + run: composer test:coverage + env: + DB_CONNECTION: pgsql + DB_HOST: 127.0.0.1 + DB_PORT: 5432 + DB_DATABASE: deployer + DB_USERNAME: deployer + DB_PASSWORD: password + + # e2e: + # needs: [conflicts, analyse, format] + + # runs-on: ubuntu-latest + + # services: + # postgres: + # image: postgres:12 + # env: + # POSTGRES_DB: homestead + # POSTGRES_USER: homestead + # POSTGRES_PASSWORD: password + # ports: + # - 5432:5432 + # options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + # steps: + # - name: Checkout code + # uses: actions/checkout@v3 + + # - name: Setup PHP + # uses: shivammathur/setup-php@v2 + # with: + # php-version: "8.0" + # extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite, pcov + # coverage: pcov + + # - name: Cache dependencies + # uses: actions/cache@v3 + # with: + # path: ~/.composer/cache/files + # key: dependencies-composer-${{ hashFiles('composer.json') }} + + # - name: Install Composer dependencies + # run: composer install --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + # - name: Prepare the application + # run: cp .env.dusk .env + + # - name: Generate Application Key + # run: php artisan key:generate + + # - name: Upgrade Chrome Driver + # run: php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1` + + # - name: Start Chrome Driver + # run: ./vendor/laravel/dusk/bin/chromedriver-linux & + + # - name: Run Laravel Server + # run: php artisan serve & + + # - name: Run Dusk Tests + # run: php artisan dusk + + # - name: Upload Screenshots + # uses: actions/upload-artifact@v1 + # if: failure() + # with: + # name: dusk-screenshots + # path: tests/Browser/screenshots + + # - name: Upload Console + # uses: actions/upload-artifact@v1 + # if: failure() + # with: + # name: dusk-console + # path: tests/Browser/console + + # - name: Upload Logs + # uses: actions/upload-artifact@v1 + # if: failure() + # with: + # name: dusk-logs + # path: storage/logs diff --git a/.github/workflows/deps.yml b/.github/workflows/deps.yml new file mode 100644 index 0000000..85e827b --- /dev/null +++ b/.github/workflows/deps.yml @@ -0,0 +1,87 @@ +name: Dependencies + +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: + +jobs: + php: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite + coverage: none + + - name: Update PHP dependencies + run: npx @faustbrian/node-composer-check-updates --caret-minor + + - name: Install PHP dependencies + run: composer update --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + - name: Install JS dependencies + run: yarn --ignore-engines + + - name: Rebuild assets + run: yarn prod + + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.GH_TOKEN }} + commit-message: 'chore: update PHP dependencies' + committer: GitHub + author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> + branch: chore/update-php-dependencies + delete-branch: true + title: 'chore: update PHP dependencies' + draft: false + + js: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, dom, fileinfo, intl, gd, imagick, bcmath, soap, zip, sqlite + coverage: none + + - name: Install PHP dependencies + run: composer install --no-ansi --no-interaction --no-progress --prefer-dist --optimize-autoloader --ignore-platform-reqs + + - name: Update JS dependencies + run: npx npm-check-updates --configFilePath ./vendor/arkecosystem/foundation/ + + - name: Install Updated JS dependencies + run: yarn --ignore-engines + + - name: Rebuild assets + run: yarn prod + + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + token: ${{ secrets.GH_TOKEN }} + commit-message: 'chore: update JavaScript dependencies' + committer: GitHub + author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> + branch: chore/update-javascript-dependencies + delete-branch: true + title: 'chore: update JavaScript dependencies' + draft: false diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml new file mode 100644 index 0000000..5fb806c --- /dev/null +++ b/.github/workflows/label.yml @@ -0,0 +1,19 @@ +name: Labels + +on: + pull_request: + types: [ready_for_review, synchronize, opened] + +jobs: + assign: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + + - uses: srvaroa/labeler@master + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml new file mode 100644 index 0000000..f0bbed3 --- /dev/null +++ b/.github/workflows/ui.yml @@ -0,0 +1,73 @@ +name: UI + +on: + pull_request: + paths: + - '**.css' + - '**.js' + - '**.php' + - '**.svg' + +jobs: + prettier: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Install + run: yarn install --frozen-lockfile + + - name: Run prettier + run: yarn run prettier --write 'resources/**/*.{css,js,vue}' + + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: 'style: resolve style guide violations' + branch: ${{ github.head_ref }} + + rustywind: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Format + run: | + export PATH="$(yarn global bin):$PATH" + yarn global add rustywind + rustywind --write resources/views + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: 'style: resolve style guide violations' + branch: ${{ github.head_ref }} + + svg: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GH_TOKEN }} + + - name: Optimize SVGs + uses: ericcornelissen/svgo-action@v3 + id: svgo + with: + ignore: public/vendor/**/*.svg + repo-token: ${{ secrets.GH_TOKEN }} + svgo-config: .svgo.js + + - name: Commit optimizations + uses: stefanzweifel/git-auto-commit-action@v4 + if: ${{steps.svgo.outputs.DID_OPTIMIZE}} + with: + commit_message: Optimize ${{steps.svgo.outputs.OPTIMIZED_COUNT}} SVG(s) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d10de2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +_ide_helper_models.php +_ide_helper.php +.coverage +.env +.env.dusk.local +.idea/ +.php-cs-fixer.cache +.phpstorm.meta.php +.phpunit.result.cache +*.sqlite +**/.DS_Store +/node_modules +/public/hot +/storage/*.key +/vendor +coverage.xml +database/*.sqlite +error_log +Homestead.json +Homestead.yaml +npm-debug.log +package-lock.json +yarn-error.log +auth.json diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 0000000..ff4e8d8 --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,3 @@ +{ + "resources/js/**/*.js": ["npm run prod"] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..0daad86 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +public/ +vendor/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..46124e3 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 120, + "singleQuote": true, + "tabWidth": 4, + "trailingComma": "es5" +} diff --git a/.svgo.js b/.svgo.js new file mode 100644 index 0000000..7eeb0c0 --- /dev/null +++ b/.svgo.js @@ -0,0 +1,16 @@ +module.exports = { +plugins: [ + { + name: 'preset-default', + params: { + overrides: { + cleanupIDs: { + preservePrefixes: [ + 'keep_', + ], + }, + } + } + }, +], +}; diff --git a/.svgo.yml b/.svgo.yml new file mode 100644 index 0000000..9d7c83f --- /dev/null +++ b/.svgo.yml @@ -0,0 +1,2 @@ +plugins: + - cleanupIDs: false \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..806b117 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @faustbrian @ItsANameToo @samharperpittam @alexbarnsley diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..810fce6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/app/App/BaseApplication.php b/app/App/BaseApplication.php new file mode 100644 index 0000000..c3eadfa --- /dev/null +++ b/app/App/BaseApplication.php @@ -0,0 +1,17 @@ +basePath.DIRECTORY_SEPARATOR.'app/App'.($path !== '' ? DIRECTORY_SEPARATOR.$path : $path); + } +} diff --git a/app/App/Collaborator/Components/CollaboratorPermissionsModal.php b/app/App/Collaborator/Components/CollaboratorPermissionsModal.php new file mode 100644 index 0000000..56b0a22 --- /dev/null +++ b/app/App/Collaborator/Components/CollaboratorPermissionsModal.php @@ -0,0 +1,34 @@ + 'setPermissions']; + + public function setPermissions(array $permissions): void + { + $this->permissions = $permissions; + + $this->openModal(); + } + + public function getAvailablePermissionsProperty(): Collection + { + return collect(Collaborator::availablePermissions()); + } +} diff --git a/app/App/Collaborator/Components/DeclineInvitationModal.php b/app/App/Collaborator/Components/DeclineInvitationModal.php new file mode 100644 index 0000000..047dd53 --- /dev/null +++ b/app/App/Collaborator/Components/DeclineInvitationModal.php @@ -0,0 +1,65 @@ + 'showModal']; + + public function showModal(int $id): void + { + $this->invitationId = $id; + $this->invitation = Invitation::find($id); + } + + public function close(): void + { + $this->invitationId = null; + + $this->modalClosed(); + } + + public function decline(): Redirector|RedirectResponse + { + $request = request(); + if (! TokenInvitationController::canBeHandled($request, $this->invitation)) { + return redirect()->route('user.teams'); + } + + /** @var Token $token */ + $token = $this->invitation?->token; + + $this->invitation?->delete(); + + alert('invitations.messages.decline_invitation', FlashType::SUCCESS); + + /** @var User $user */ + $user = $request->user(); + + $token->user->notify(new CollaboratorDeclinedInvite($token, $user)); + + return redirect()->route('user.teams')->with('status', TokenInvitationController::ALERT_STATUS); + } +} diff --git a/app/App/Collaborator/Components/DeleteCollaborator.php b/app/App/Collaborator/Components/DeleteCollaborator.php new file mode 100644 index 0000000..86fbc4c --- /dev/null +++ b/app/App/Collaborator/Components/DeleteCollaborator.php @@ -0,0 +1,69 @@ + 'askForConfirmation']; + + public function askForConfirmation(int $id): void + { + $this->collaboratorId = $id; + $this->name = User::findOrFail($id)->name; + } + + public function destroy(): void + { + $this->authorize('deleteCollaborator', $this->token); + + $collaborator = User::findOrFail($this->collaboratorId); + + abort_unless($this->canBeRemoved($collaborator), 403); + + $this->token->stopSharingWith($collaborator); + + $this->reset(); + + $this->emit('refreshCollaborators'); + + $this->toast(trans('tokens.collaborators.removed'), 'success'); + + $this->modalClosed(); + } + + public function close(): void + { + $this->collaboratorId = null; + $this->name = null; + + $this->modalClosed(); + } + + private function canBeRemoved(User $collaborator): bool + { + return $this->user->id !== $collaborator->id && $collaborator->id !== $this->token->user->id; + } +} diff --git a/app/App/Collaborator/Components/InviteCollaborator.php b/app/App/Collaborator/Components/InviteCollaborator.php new file mode 100644 index 0000000..9c8d023 --- /dev/null +++ b/app/App/Collaborator/Components/InviteCollaborator.php @@ -0,0 +1,52 @@ +authorize('createCollaborator', $this->token); + + $data = $this->validate([ + 'email' => ['required', 'email', 'max:255'], + 'permissions' => ['required', 'array'], + 'permissions.*' => ['required', 'string', Rule::in($this->getAvailablePermissionsProperty()->toArray())], + ]); + + resolve(InviteCollaboratorAction::class)($this->token, strtolower($data['email']), $this->permissions); + + $this->email = null; + $this->permissions = []; + + $this->emit('refreshCollaborators'); + + $this->toast(trans('tokens.invitation_sent')); + } + + public function getAvailablePermissionsProperty(): Collection + { + return collect(Collaborator::availablePermissions()); + } +} diff --git a/app/App/Collaborator/Components/LeaveTeamModal.php b/app/App/Collaborator/Components/LeaveTeamModal.php new file mode 100644 index 0000000..bbc7e4d --- /dev/null +++ b/app/App/Collaborator/Components/LeaveTeamModal.php @@ -0,0 +1,62 @@ + 'showModal']; + + public function showModal(int $id): void + { + $this->tokenId = $id; + $this->token = Token::find($id); + } + + public function close(): void + { + $this->tokenId = null; + + $this->closeModal(); + } + + public function leave(): Redirector|RedirectResponse + { + /** @var ?User */ + $user = $this->user; + + if ($user !== null && $this->token !== null && ! $user->ownsToken($this->token)) { + $this->token->stopSharingWith($user); + } + + $this->tokenId = null; + + $this->closeModal(); + + alert('tokens.messages.left_team', FlashType::SUCCESS, ['team' => $this->token?->name]); + + return redirect()->route('user.teams')->with('status', self::ALERT_STATUS); + } +} diff --git a/app/App/Collaborator/Components/MailedInvitations.php b/app/App/Collaborator/Components/MailedInvitations.php new file mode 100644 index 0000000..3e9384b --- /dev/null +++ b/app/App/Collaborator/Components/MailedInvitations.php @@ -0,0 +1,43 @@ + '$refresh']; + + public function cancel(string $invitationId): void + { + $invitation = Invitation::findOrFail($invitationId); + + /** @var User $user */ + $user = auth()->user(); + abort_unless($user->ownsToken($invitation->token), 403); + + $invitation->delete(); + + $this->emit('refreshCollaborators'); + + $this->toast(trans('tokens.invitations.mailed_invitation_removed_success'), 'success'); + } + + public function getInvitationsProperty(): Collection + { + return $this->token->invitations; + } +} diff --git a/app/App/Collaborator/Components/ManageCollaborators.php b/app/App/Collaborator/Components/ManageCollaborators.php new file mode 100644 index 0000000..8adedc1 --- /dev/null +++ b/app/App/Collaborator/Components/ManageCollaborators.php @@ -0,0 +1,31 @@ + '$refresh']; + + public function getCollaboratorsProperty(): Collection + { + return $this->token->collaborators()->where('user_id', '!=', Auth::id())->get(); + } + + public function getUserProperty(): User + { + return $this->token->collaborators()->where('user_id', Auth::id())->firstOrFail(); + } +} diff --git a/app/App/Collaborator/Components/UpdateCollaborator.php b/app/App/Collaborator/Components/UpdateCollaborator.php new file mode 100644 index 0000000..be9dde0 --- /dev/null +++ b/app/App/Collaborator/Components/UpdateCollaborator.php @@ -0,0 +1,70 @@ + 'edit']; + + public function edit(int $id): void + { + $collaborator = $this->token->collaborators()->findOrFail($id); + + $this->collaboratorId = $id; + $this->permissions = $collaborator->pivot->permissions ?? []; + } + + public function update(): void + { + $this->authorize('createCollaborator', $this->token); + + $this->validate([ + 'permissions' => ['required', 'array'], + 'permissions.*' => ['required', 'string', Rule::in($this->getAvailablePermissionsProperty()->toArray())], + ]); + + $this->token->collaborators()->updateExistingPivot( + $this->collaboratorId, + ['permissions' => $this->permissions] + ); + + $this->collaboratorId = null; + $this->permissions = []; + + $this->emit('refreshCollaborators'); + + $this->toast(trans('tokens.collaborators.permissions_updated_success'), 'success'); + } + + public function getAvailablePermissionsProperty(): Collection + { + return collect(Collaborator::availablePermissions()); + } + + public function close(): void + { + $this->collaboratorId = null; + $this->permissions = []; + } +} diff --git a/app/App/Collaborator/Mail/InviteExistingUser.php b/app/App/Collaborator/Mail/InviteExistingUser.php new file mode 100644 index 0000000..251c442 --- /dev/null +++ b/app/App/Collaborator/Mail/InviteExistingUser.php @@ -0,0 +1,51 @@ +fromInvitation($this->invitation, [ + 'content' => trans('notifications.subjects.new_invitation'), + ]) + ->withAction(trans('actions.view'), route('user.teams')) + ->success() + ->getContent(); + } + + public function toMail(): MailMessage + { + return (new MailMessage()) + ->subject($subject = trans('mails.subjects.new_invitation')) + ->view('mails.invite-existing-user', [ + 'subject' => $subject, + 'userName' => optional($this->invitation->user)->name ?? null, + 'tokenName' => $this->invitation->token->name, + 'url' => route('register', ['invitation' => $this->invitation->uuid]), + ]); + } +} diff --git a/app/App/Collaborator/Mail/InviteNewUser.php b/app/App/Collaborator/Mail/InviteNewUser.php new file mode 100644 index 0000000..d346da2 --- /dev/null +++ b/app/App/Collaborator/Mail/InviteNewUser.php @@ -0,0 +1,32 @@ +subject($subject = trans('mails.subjects.new_invitation')) + ->view('mails.invite-new-user', [ + 'subject' => $subject, + 'tokenName' => $this->invitation->token->name, + 'url' => route('register', ['invitation' => $this->invitation->uuid]), + ]); + } +} diff --git a/app/App/Collaborator/Notifications/CollaboratorAcceptedInvite.php b/app/App/Collaborator/Notifications/CollaboratorAcceptedInvite.php new file mode 100644 index 0000000..d49607a --- /dev/null +++ b/app/App/Collaborator/Notifications/CollaboratorAcceptedInvite.php @@ -0,0 +1,37 @@ +fromToken($this->token, [ + 'content' => trans('notifications.subjects.collaborator_accepted_invitation', ['collaborator' => $this->user->name]), + ]) + ->withAction(trans('actions.view'), route('user.teams')) + ->withUser($this->user) + ->success() + ->getContent(); + } +} diff --git a/app/App/Collaborator/Notifications/CollaboratorDeclinedInvite.php b/app/App/Collaborator/Notifications/CollaboratorDeclinedInvite.php new file mode 100644 index 0000000..574931c --- /dev/null +++ b/app/App/Collaborator/Notifications/CollaboratorDeclinedInvite.php @@ -0,0 +1,37 @@ +fromToken($this->token, [ + 'content' => trans('notifications.subjects.collaborator_refused_invitation', ['collaborator' => $this->user->name]), + ]) + ->withAction(trans('actions.view'), route('user.teams')) + ->withUser($this->user) + ->warning() + ->getContent(); + } +} diff --git a/app/App/Console/Commands/CheckRemoteServerExistence.php b/app/App/Console/Commands/CheckRemoteServerExistence.php new file mode 100644 index 0000000..7d7a908 --- /dev/null +++ b/app/App/Console/Commands/CheckRemoteServerExistence.php @@ -0,0 +1,25 @@ +serverProvider->client()->valid()) { + $this->notifiables($this->serverProvider)->each->notify(new ServerProviderAuthenticationFailed($this->serverProvider)); + + $this->serverProvider->delete(); + + ServerProviderDeleted::dispatch($this->serverProvider); + } + } + + /** + * @return Collection + */ + private function notifiables(ServerProvider $provider) : Collection + { + return collect([ + $provider->user(), + $provider->token->user, + ])->filter()->unique('id')->values(); + } +} diff --git a/app/App/Console/Commands/Jobs/PingServer.php b/app/App/Console/Commands/Jobs/PingServer.php new file mode 100644 index 0000000..56a9a18 --- /dev/null +++ b/app/App/Console/Commands/Jobs/PingServer.php @@ -0,0 +1,56 @@ +isReachable()) { + $this->server->token->collaborators->each->notify(new ServerUnreachable($this->server)); + + $this->server->markAsOffline(); + } + } + + private function isReachable(): bool + { + while ($this->failureCount <= 5) { + $process = new Process(['ping', '-c 3', '-i 5', $this->server->ip_address]); + $process->setTimeout(15); + + $response = ShellProcessRunner::run($process); + + if ($response->exitCode === 0) { + break; + } + + $this->failureCount++; + } + + return $this->failureCount < 3; + } +} diff --git a/app/App/Console/Commands/Jobs/RemoteServerExistence.php b/app/App/Console/Commands/Jobs/RemoteServerExistence.php new file mode 100644 index 0000000..e564a18 --- /dev/null +++ b/app/App/Console/Commands/Jobs/RemoteServerExistence.php @@ -0,0 +1,37 @@ +server->serverProvider->client()->server($this->server->provider_server_id); + } catch (ServerNotFound) { + $this->server->delete(); + } catch (Throwable) { + // ignore this? + } + } +} diff --git a/app/App/Console/Commands/Jobs/SyncServerRemoteAddress.php b/app/App/Console/Commands/Jobs/SyncServerRemoteAddress.php new file mode 100644 index 0000000..334f814 --- /dev/null +++ b/app/App/Console/Commands/Jobs/SyncServerRemoteAddress.php @@ -0,0 +1,42 @@ +server->ip_address === null) { + $response = $this->server->serverProvider->client()->server($this->server->provider_server_id); + + $this->server->update([ + 'ip_address' => $response->remoteAddress, + ]); + } + } + + public function backoff() : array + { + return [3, 5, 10]; + } +} diff --git a/app/App/Console/Commands/MaintainInvitations.php b/app/App/Console/Commands/MaintainInvitations.php new file mode 100644 index 0000000..79a1c13 --- /dev/null +++ b/app/App/Console/Commands/MaintainInvitations.php @@ -0,0 +1,24 @@ +filter->isExpired() as $invitation) { + $invitation->delete(); + } + }); + } +} diff --git a/app/App/Console/Commands/MaintainServerProviderKeys.php b/app/App/Console/Commands/MaintainServerProviderKeys.php new file mode 100644 index 0000000..08658d4 --- /dev/null +++ b/app/App/Console/Commands/MaintainServerProviderKeys.php @@ -0,0 +1,25 @@ +status, 'failed')) { + $server->token->user->notify(new ServerFailedDeployment($server)); + + $creator = $server->creator(); + + if ($creator && $creator->isNot($server->token->user)) { + $creator->notify(new ServerFailedDeployment($server)); + } + + $server->delete(); + } + }); + } +} diff --git a/app/App/Console/Commands/RunPlaybookCommand.php b/app/App/Console/Commands/RunPlaybookCommand.php new file mode 100644 index 0000000..0331a2f --- /dev/null +++ b/app/App/Console/Commands/RunPlaybookCommand.php @@ -0,0 +1,147 @@ +environment() !== 'local') { + $this->error('This command can only be run in the local environment!'); + } + + $playbookName = $this->argument('playbook'); + + if ($playbookName === null) { + $availablePlaybooks = $this->getAvailablePlaybooks(); + + $this->comment('Choose a playbook: '.PHP_EOL); + + foreach ($availablePlaybooks as $availablePlaybook) { + $this->comment("- {$availablePlaybook}"); + } + + $this->comment(''); + + $playbookName = $this->askPlaybookName($availablePlaybooks); + } + + $playbookDefinition = $this->resolvePlaybookDefinition($playbookName); + + $this->migrate(); + + $this->runPlaybook($playbookDefinition); + } + + private function migrate(): void + { + $this->info('Clearing the database'); + + $this->call('migrate:fresh', ['--force']); + } + + private function runPlaybook(PlaybookDefinition $definition): void + { + foreach ($definition->playbook->before() as $before) { + $this->runPlaybook( + $this->resolvePlaybookDefinition($before) + ); + } + + for ($i = 1; $i <= $definition->times; $i++) { + if ($definition->once && $this->definitionHasRun($definition)) { + break; + } + + $this->infoRunning($definition->playbook, $i); + + $definition->playbook->run($this->input, $this->output); + + $definition->playbook->hasRun(); + + $this->ranDefinitions[$definition->id] = ($this->ranDefinitions[$definition->id] ?? 0) + 1; + } + + foreach ($definition->playbook->after() as $after) { + $this->runPlaybook( + $this->resolvePlaybookDefinition($after) + ); + } + } + + private function askPlaybookName(array $availablePlaybooks): string + { + $helper = $this->getHelper('question'); + + $question = new Question(''); + + $question->setAutocompleterValues($availablePlaybooks); + + $playbookName = (string) $helper->ask($this->input, $this->output, $question); + + if ($playbookName === '') { + $this->error('Please choose a playbook'); + + return $this->askPlaybookName($availablePlaybooks); + } + + return $playbookName; + } + + private function getAvailablePlaybooks(): array + { + /** + * @var array + */ + $files = scandir(__DIR__.'/../Playbooks'); + + unset($files[0], $files[1]); + + return array_map(fn (string $file) => str_replace('.php', '', $file), $files); + } + + private function resolvePlaybookDefinition(mixed $class): PlaybookDefinition + { + if ($class instanceof PlaybookDefinition) { + return $class; + } + + if ($class instanceof Playbook) { + return new PlaybookDefinition(get_class($class)); + } + + $className = $class; + + if (! Str::startsWith($class, ['\\App\\Console\\Playbooks', 'App\\Console\\Playbooks'])) { + $className = "\\App\\Console\\Playbooks\\{$class}"; + } + + return new PlaybookDefinition($className); + } + + private function infoRunning(Playbook $playbook, int $i): void + { + $playbookName = get_class($playbook); + + $this->info("Running playbook `{$playbookName}` (#{$i})"); + } + + private function definitionHasRun(PlaybookDefinition $definition): bool + { + return array_key_exists($definition->id, $this->ranDefinitions); + } +} diff --git a/app/App/Console/Commands/SyncServerRemoteAddresses.php b/app/App/Console/Commands/SyncServerRemoteAddresses.php new file mode 100644 index 0000000..5a28baa --- /dev/null +++ b/app/App/Console/Commands/SyncServerRemoteAddresses.php @@ -0,0 +1,27 @@ +whereNotNull('provider_server_id') + ->chunkById(5000, function ($servers): void { + foreach ($servers as $server) { + SyncServerRemoteAddress::dispatch($server); + } + }); + } +} diff --git a/app/App/Console/Kernel.php b/app/App/Console/Kernel.php new file mode 100644 index 0000000..0e1b5ac --- /dev/null +++ b/app/App/Console/Kernel.php @@ -0,0 +1,112 @@ +command(SyncServerRemoteAddresses::class) + ->everyMinute() + ->withoutOverlapping(); + + $schedule + ->command(CheckRemoteServerExistence::class) + ->hourly() + ->withoutOverlapping(); + + $schedule + ->command(PingRemoteServers::class) + ->everyFifteenMinutes() + ->withoutOverlapping(); + + $schedule + ->command(MaintainServerProviderKeys::class) + ->hourly() + ->withoutOverlapping(); + + $schedule + ->command(MaintainInvitations::class) + ->everyTenMinutes() + ->withoutOverlapping(); + + $schedule + ->command(IndexServerProviderPlans::class) + ->daily() + ->withoutOverlapping(); + + $schedule + ->command(IndexServerProviderRegions::class) + ->twiceDaily() + ->withoutOverlapping(); + + $schedule + ->command(IndexServerProviderImages::class) + ->daily() + ->withoutOverlapping(); + + $schedule + ->command(PurgeServersWithFailedDeployments::class) + ->everyThirtyMinutes() + ->withoutOverlapping(); + + $schedule + ->command('telescope:prune') + ->environments(['local']) + ->twiceDaily(); + + $schedule + ->command('horizon:snapshot') + ->everyFiveMinutes(); + + $schedule->command('personal-data-export:clean')->daily(); + + // TODO: Do we want to use onFailure onSuccess hooks ? + + /* + $schedule + ->command('backup:clean') + ->daily() + ->at('01:00') + ->withoutOverlapping(); + + $schedule + ->command('backup:run') + ->daily() + ->at('01:10') + ->withoutOverlapping(); + */ + + // TODO: Command to upload the backup + } + + /** + * Register the commands for the application. + */ + protected function commands() + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} diff --git a/app/App/Console/Playbooks/BarePlaybook.php b/app/App/Console/Playbooks/BarePlaybook.php new file mode 100644 index 0000000..1b7bcd1 --- /dev/null +++ b/app/App/Console/Playbooks/BarePlaybook.php @@ -0,0 +1,24 @@ +writeln('[Playbook] Bare - success'); + } +} diff --git a/app/App/Console/Playbooks/CoinPlaybook.php b/app/App/Console/Playbooks/CoinPlaybook.php new file mode 100644 index 0000000..3071ba9 --- /dev/null +++ b/app/App/Console/Playbooks/CoinPlaybook.php @@ -0,0 +1,20 @@ +create([ + 'name' => 'ARK', + 'symbol' => 'ARK', + ]); + } +} diff --git a/app/App/Console/Playbooks/DatabaseNotificationPlaybook.php b/app/App/Console/Playbooks/DatabaseNotificationPlaybook.php new file mode 100644 index 0000000..f49827e --- /dev/null +++ b/app/App/Console/Playbooks/DatabaseNotificationPlaybook.php @@ -0,0 +1,17 @@ +count(5)->create(); + } +} diff --git a/app/App/Console/Playbooks/DemoPlaybook.php b/app/App/Console/Playbooks/DemoPlaybook.php new file mode 100644 index 0000000..7988c4d --- /dev/null +++ b/app/App/Console/Playbooks/DemoPlaybook.php @@ -0,0 +1,124 @@ +each(function ($user): void { + Invitation::factory()->count(10)->create(['user_id' => $user->id]); + + $key = SecureShellKey::factory()->create(['user_id' => $user->id]); + + Token::factory()->count(5)->create(['user_id' => $user->id])->each(function ($token) use ($key, $user) : void { + TokenCreated::dispatch($token); + + $token->slug = Str::slug($token->name); + + $token->setMetaAttribute('repoName', $token->slug); + $token->setMetaAttribute('onboarding.configuration_status', 'completed'); + $token->setMetaAttribute('onboarding.server_providers_status', 'completed'); + $token->setMetaAttribute('onboarding.server_config_status', 'completed'); + $token->setMetaAttribute('onboarding.secure_shell_keys_status', 'completed'); + $token->setMetaAttribute('onboarding.collaborators_status', 'completed'); + $token->setMetaAttribute('onboarding.servers_status', 'completed'); + + $token->setStatus(TokenStatusEnum::FINISHED); + + $token->secureShellKeys()->sync($key->id); + + $serverProvider = ServerProvider::factory()->digitalocean()->create([ + 'token_id' => $token->id, + ]); + + $serverProvider->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + ServerProviderCreated::dispatch($serverProvider); + + $serverProvider->plans()->syncWithoutDetaching(ServerProviderPlan::factory()->count(3)->create()); + $serverProvider->regions()->syncWithoutDetaching(ServerProviderRegion::factory()->count(3)->create()); + $serverProvider->images()->syncWithoutDetaching(ServerProviderImage::factory()->count(3)->create()); + + $token + ->networks() + ->each(function ($network) use ($token, $user) : void { + $server = $token->servers()->create([ + 'network_id' => $network->id, + 'server_provider_id' => $token->serverProviders()->first()->id, + 'server_provider_plan_id' => $token->serverProviders()->first()->plans()->first()->id, + 'server_provider_region_id' => $token->serverProviders()->first()->regions()->first()->id, + 'server_provider_image_id' => $token->serverProviders()->first()->images()->first()->id, + 'name' => Haiku::name(), + 'preset' => PresetTypeEnum::GENESIS, + ]); + + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + $this->fakeServerCreatedEvent($server); + + $user->notify(new ServerDeployed($server)); + }); + }); + }); + } + + /** + * We should usually call a `ServerCreated::dispatch($server);` event, so + * the following listeners are called. However, since we are using a fake + * server, the `CreateServerOnProvider` listener had problems connecting to + * the server provider for provisioning so I am manually changing the server + * status and running the listeners. + * + * @param Server $server + * + * @return void + */ + private function fakeServerCreatedEvent($server): void + { + $event = new ServerCreated($server); + + (new ListenForActivityLogs())->handle($event); + + // Instead of (new CreateServerOnProvider())->handle($event); + $server->update([ + 'provider_server_id' => rand(5, 15), + 'ip_address' => '127.0.0.1', + 'provisioning_job_dispatched_at' => now(), + ]); + $server->setStatus('provisioning'); + $server->markAsOnline(); + } +} diff --git a/app/App/Console/Playbooks/DevelopmentPlaybook.php b/app/App/Console/Playbooks/DevelopmentPlaybook.php new file mode 100644 index 0000000..4346f5a --- /dev/null +++ b/app/App/Console/Playbooks/DevelopmentPlaybook.php @@ -0,0 +1,131 @@ +each(function ($user): void { + Invitation::factory()->count(10)->create(['user_id' => $user->id]); + + $key = SecureShellKey::factory()->create(['user_id' => $user->id]); + + Token::factory()->count(5)->create(['user_id' => $user->id])->each(function ($token) use ($key, $user) : void { + TokenCreated::dispatch($token); + + $token->slug = Str::slug($token->name); + + $token->setMetaAttribute('repoName', $token->slug); + $token->setMetaAttribute('onboarding.configuration_status', 'completed'); + $token->setMetaAttribute('onboarding.server_providers_status', 'completed'); + $token->setMetaAttribute('onboarding.server_config_status', 'completed'); + $token->setMetaAttribute('onboarding.secure_shell_keys_status', 'completed'); + $token->setMetaAttribute('onboarding.collaborators_status', 'completed'); + $token->setMetaAttribute('onboarding.servers_status', 'completed'); + + $token->setStatus(TokenStatusEnum::FINISHED); + + $token->secureShellKeys()->sync($key->id); + + $serverProvider = ServerProvider::factory()->digitalocean()->create([ + 'token_id' => $token->id, + ]); + + $serverProvider->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + ServerProviderCreated::dispatch($serverProvider); + + $serverProvider->plans()->syncWithoutDetaching(ServerProviderPlan::factory()->count(3)->create()); + $serverProvider->regions()->syncWithoutDetaching(ServerProviderRegion::factory()->count(3)->create()); + $serverProvider->images()->syncWithoutDetaching(ServerProviderImage::factory()->count(3)->create()); + + $token + ->networks() + ->each(function ($network) use ($token, $user) : void { + $server = $token->servers()->create([ + 'network_id' => $network->id, + 'server_provider_id' => $token->serverProviders()->first()->id, + 'server_provider_plan_id' => $token->serverProviders()->first()->plans()->first()->id, + 'server_provider_region_id' => $token->serverProviders()->first()->regions()->first()->id, + 'server_provider_image_id' => $token->serverProviders()->first()->images()->first()->id, + 'name' => Haiku::name(), + 'preset' => PresetTypeEnum::GENESIS, + ]); + + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + $this->fakeServerCreatedEvent($server); + + $user->notify(new ServerDeployed($server)); + }); + }); + }); + } + + /** + * We should usually call a `ServerCreated::dispatch($server);` event, so + * the following listeners are called. However, since we are using a fake + * server, the `CreateServerOnProvider` listener had problems connecting to + * the server provider for provisioning so I am manually changing the server + * status and running the listeners. + * + * @param Server $server + * + * @return void + */ + private function fakeServerCreatedEvent($server): void + { + $event = new ServerCreated($server); + + (new ListenForActivityLogs())->handle($event); + + // Instead of (new CreateServerOnProvider())->handle($event); + $server->update([ + 'provider_server_id' => rand(5, 15), + 'ip_address' => '127.0.0.1', + 'provisioning_job_dispatched_at' => now(), + ]); + $server->setStatus('provisioning'); + $server->markAsOnline(); + } +} diff --git a/app/App/Console/Playbooks/InvitationPlaybook.php b/app/App/Console/Playbooks/InvitationPlaybook.php new file mode 100644 index 0000000..694c6ea --- /dev/null +++ b/app/App/Console/Playbooks/InvitationPlaybook.php @@ -0,0 +1,17 @@ +count(10)->create(); + } +} diff --git a/app/App/Console/Playbooks/NetworkPlaybook.php b/app/App/Console/Playbooks/NetworkPlaybook.php new file mode 100644 index 0000000..9925852 --- /dev/null +++ b/app/App/Console/Playbooks/NetworkPlaybook.php @@ -0,0 +1,17 @@ +count(10)->create(); + } +} diff --git a/app/App/Console/Playbooks/NotificationPlaybook.php b/app/App/Console/Playbooks/NotificationPlaybook.php new file mode 100644 index 0000000..1bbbd39 --- /dev/null +++ b/app/App/Console/Playbooks/NotificationPlaybook.php @@ -0,0 +1,101 @@ +create(['email' => 'notifications@ark.io']); + $collaborator = User::factory()->create(); + $token = Token::factory()->withDefaultNetworks()->create([ + 'user_id' => $user->id, + 'name' => 'MyNotificationChain', + ]); + $network = Network::factory()->ownedBy($token)->create(); + + $serverProvider = ServerProvider::factory()->digitalocean()->create([ + 'token_id' => $token->id, + ]); + + $serverProvider->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + $serverProvider->plans()->syncWithoutDetaching(ServerProviderPlan::factory()->count(3)->create()); + $serverProvider->regions()->syncWithoutDetaching(ServerProviderRegion::factory()->count(3)->create()); + $serverProvider->images()->syncWithoutDetaching(ServerProviderImage::factory()->count(3)->create()); + + $server = $token->servers()->create([ + 'network_id' => $network->id, + 'server_provider_id' => $token->serverProviders()->first()->id, + 'server_provider_plan_id' => $token->serverProviders()->first()->plans()->first()->id, + 'server_provider_region_id' => $token->serverProviders()->first()->regions()->first()->id, + 'server_provider_image_id' => $token->serverProviders()->first()->images()->first()->id, + 'name' => Haiku::name(), + 'preset' => PresetTypeEnum::GENESIS, + ]); + $server->setStatus('provisioning'); + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + // Token + $user->notify(new TokenDeleted($token)); + + // Server + $user->notify(new ServerDeployed($server)); + $user->notify(new ServerDeleted($server)); + $user->notify(new ServerFailedDeployment($server)); + $user->notify(new ServerFailedToCreateOnProvider($serverProvider, $server->name)); + $user->notify(new ServerProvisioned($server)); + $user->notify(new ServerUnreachable($server)); + + // Server Provider + $user->notify(new IndexServerProviderImagesFailed($serverProvider)); + $user->notify(new IndexServerProviderPlansFailed($serverProvider)); + $user->notify(new IndexServerProviderRegionsFailed($serverProvider)); + + $user->notify(new ServerProviderAuthenticationFailed($serverProvider)); + $user->notify(new ServerProviderSecureShellKeyAdditionFailed($serverProvider)); + $user->notify(new ServerProviderSecureShellKeyLimitReached($serverProvider)); + $user->notify(new ServerProviderSecureShellKeyRemovalFailed($serverProvider)); + $user->notify(new ServerProviderSecureShellKeyUniqueness($serverProvider)); + $user->notify(new ServerProviderServerRemovalFailed($serverProvider)); + + // Collaborator + $user->notify(new CollaboratorAcceptedInvite($token, $collaborator)); + $user->notify(new CollaboratorDeclinedInvite($token, $collaborator)); + } +} diff --git a/app/App/Console/Playbooks/Playbook.php b/app/App/Console/Playbooks/Playbook.php new file mode 100644 index 0000000..db79a4e --- /dev/null +++ b/app/App/Console/Playbooks/Playbook.php @@ -0,0 +1,45 @@ +playbook = app($className); + $this->id = get_class($this->playbook); + } + + public static function times(string $className, int $times): self + { + $definition = new static($className); + + $definition->times = $times; + + return $definition; + } + + public static function once(string $className): self + { + $definition = new static($className); + + $definition->once = true; + + return $definition; + } +} diff --git a/app/App/Console/Playbooks/SecureShellKeyPlaybook.php b/app/App/Console/Playbooks/SecureShellKeyPlaybook.php new file mode 100644 index 0000000..78b6da5 --- /dev/null +++ b/app/App/Console/Playbooks/SecureShellKeyPlaybook.php @@ -0,0 +1,17 @@ +count(10)->create(); + } +} diff --git a/app/App/Console/Playbooks/ServerPlaybook.php b/app/App/Console/Playbooks/ServerPlaybook.php new file mode 100644 index 0000000..82a4782 --- /dev/null +++ b/app/App/Console/Playbooks/ServerPlaybook.php @@ -0,0 +1,48 @@ +count(10)->create()->each(function ($server): void { + $this->fakeServerCreatedEvent($server); + }); + } + + /** + * We should usually call a `ServerCreated::dispatch($server);` event, so + * the following listeners are called. However, since we are using a fake + * server, the `CreateServerOnProvider` listener had problems connecting to + * the server provider for provisioning so I am manually changing the server + * status and running the listeners. + * + * @param \Domain\Server\Models\Server $server + * + * @return void + */ + private function fakeServerCreatedEvent($server): void + { + $event = new ServerCreated($server); + + (new ListenForActivityLogs())->handle($event); + + // Instead of (new CreateServerOnProvider())->handle($event); + $server->update([ + 'provider_server_id' => rand(5, 15), + 'ip_address' => '127.0.0.1', + 'provisioning_job_dispatched_at' => now(), + ]); + $server->setStatus('provisioning'); + $server->markAsOnline(); + } +} diff --git a/app/App/Console/Playbooks/ServerProviderPlaybook.php b/app/App/Console/Playbooks/ServerProviderPlaybook.php new file mode 100644 index 0000000..794a21e --- /dev/null +++ b/app/App/Console/Playbooks/ServerProviderPlaybook.php @@ -0,0 +1,20 @@ +count(10)->create()->each(function ($serverProvider): void { + ServerProviderCreated::dispatch($serverProvider); + }); + } +} diff --git a/app/App/Console/Playbooks/TokenPlaybook.php b/app/App/Console/Playbooks/TokenPlaybook.php new file mode 100644 index 0000000..e86af28 --- /dev/null +++ b/app/App/Console/Playbooks/TokenPlaybook.php @@ -0,0 +1,23 @@ +count(10)->create()->each(function ($token): void { + TokenCreated::dispatch($token); + + $token->setStatus(TokenStatusEnum::FINISHED); + }); + } +} diff --git a/app/App/Console/Playbooks/UserPlaybook.php b/app/App/Console/Playbooks/UserPlaybook.php new file mode 100644 index 0000000..6b2a077 --- /dev/null +++ b/app/App/Console/Playbooks/UserPlaybook.php @@ -0,0 +1,17 @@ +create(['email' => 'hello@ark.io']); + } +} diff --git a/app/App/Contracts/LogsActivity.php b/app/App/Contracts/LogsActivity.php new file mode 100644 index 0000000..313c535 --- /dev/null +++ b/app/App/Contracts/LogsActivity.php @@ -0,0 +1,18 @@ + 'Amazon Web Services', + static::AZURE => 'Azure', + static::DIGITALOCEAN => 'DigitalOcean', + static::HETZNER => 'Hetzner', + static::LINODE => 'Linode', + static::VULTR => 'Vultr', + default => 'Other', + }; + } +} diff --git a/app/App/Exceptions/Handler.php b/app/App/Exceptions/Handler.php new file mode 100644 index 0000000..f696d05 --- /dev/null +++ b/app/App/Exceptions/Handler.php @@ -0,0 +1,59 @@ +> + */ + protected $dontReport = []; + + /** + * A list of the inputs that are never flashed for validation exceptions. + * + * @var array + */ + protected $dontFlash = [ + 'password', + 'password_confirmation', + ]; + + /** + * Report or log an exception. + * + * @param Throwable $exception + * @throws Throwable + */ + public function report(Throwable $exception) + { + if (app()->bound('sentry') && $this->shouldReport($exception)) { + app('sentry')->captureException($exception); + } + + parent::report($exception); + } + + /** + * Render an exception into an HTTP response. + * + * @param Request $request + * @param Throwable $exception + * + * @throws Throwable + * @return \Illuminate\Http\JsonResponse|Response|\Symfony\Component\HttpFoundation\Response + */ + public function render($request, Throwable $exception) + { + return parent::render($request, $exception); + } +} diff --git a/app/App/Http/Components/DownloadInstallScript.php b/app/App/Http/Components/DownloadInstallScript.php new file mode 100644 index 0000000..cf03aaa --- /dev/null +++ b/app/App/Http/Components/DownloadInstallScript.php @@ -0,0 +1,61 @@ +token->network($networkName); + + abort_if($network === null, 404); + + $path = $network->configurationPath(); + + if (! Storage::disk('token-config')->exists($path)) { + report(new RuntimeException('User tried to download an installation script for token [ID: '.$this->token->id.'] but the file does not exist.')); + + $this->toast(trans('pages.token.error_downloading_script'), 'error'); + + return null; + } + + return Storage::disk('token-config')->download( + $path, + $this->generateFilename($network) + ); + } + + public function availableNetworks() : Collection + { + return collect(NetworkTypeEnum::all())->filter(function ($networkName) { + $network = $this->token->network($networkName); + + return $network !== null && $network->hasProvisionedGenesis(); + })->values(); + } + + private function generateFilename(Network $network) : string + { + return sprintf('config-%s-%s.zip', Str::slug($this->token->name), $network->name); + } +} diff --git a/app/App/Http/Components/ManageWelcomeScreens.php b/app/App/Http/Components/ManageWelcomeScreens.php new file mode 100644 index 0000000..44350e4 --- /dev/null +++ b/app/App/Http/Components/ManageWelcomeScreens.php @@ -0,0 +1,44 @@ +visible = $this->user->seen_welcome_screens_at === null; + + $this->openModal(); + } + + public function close() : void + { + if ($this->hideForever) { + $this->user->touch('seen_welcome_screens_at'); + } + + $this->closeModal(); + } + + public function closeForever() : void + { + $this->user->touch('seen_welcome_screens_at'); + + $this->closeModal(); + } +} diff --git a/app/App/Http/Components/Modals/BetaNotice.php b/app/App/Http/Components/Modals/BetaNotice.php new file mode 100644 index 0000000..8bf154c --- /dev/null +++ b/app/App/Http/Components/Modals/BetaNotice.php @@ -0,0 +1,44 @@ +modalShown = ! Cookie::has('beta_agreement_at'); + } + + public function close(): void + { + if (! $this->agree) { + return; + } + + Cookie::queue('beta_agreement_at', Carbon::now(), Constants::COOKIE_EXPIRY_FOREVER); + + $this->closeModal(); + } +} diff --git a/app/App/Http/Components/UseDefaultsModal.php b/app/App/Http/Components/UseDefaultsModal.php new file mode 100644 index 0000000..5ecbcc2 --- /dev/null +++ b/app/App/Http/Components/UseDefaultsModal.php @@ -0,0 +1,48 @@ + 'showModal', + 'closeModal' => 'close', + ]; + + public function showModal(bool $isFee = false): void + { + $this->requiresConfirmation = true; + $this->isFee = $isFee; + } + + public function close(): void + { + $this->requiresConfirmation = false; + + $this->modalClosed(); + } + + public function emitDefaults(?bool $overwrite = false): void + { + if ($this->isFee === true) { + $this->emit('setFeeDefaults', $overwrite); + + return; + } + $this->emit('setDefaults', $overwrite); + } +} diff --git a/app/App/Http/Kernel.php b/app/App/Http/Kernel.php new file mode 100644 index 0000000..b5882d9 --- /dev/null +++ b/app/App/Http/Kernel.php @@ -0,0 +1,117 @@ + [ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + // \Spatie\ResponseCache\Middlewares\CacheResponse::class, + ], + + 'api' => [ + 'throttle:60,1', + 'bindings', + ], + ]; + + /** + * The application's route middleware. + * + * These middleware may be assigned to groups or used individually. + * + * @var array + */ + protected $routeMiddleware = [ + 'auth' => Authenticate::class, + 'auth.basic' => AuthenticateWithBasicAuth::class, + 'bindings' => SubstituteBindings::class, + 'cache.headers' => SetCacheHeaders::class, + 'can' => Authorize::class, + 'guest' => RedirectIfAuthenticated::class, + 'signed' => ValidateSignature::class, + 'throttle' => ThrottleRequests::class, + 'throttleWithSessionToken' => ThrottleWithSessionToken::class, + 'verified' => EnsureEmailIsVerified::class, + 'cacheResponse' => CacheResponse::class, + 'doNotCacheResponse' => DoNotCacheResponse::class, + 'onboard' => RedirectIfOnboarding::class, + 'recaptcha' => VerifyRecaptcha::class, + ]; + + /** + * The priority-sorted list of middleware. + * + * This forces non-global middleware to always be in the given order. + * + * @var array + */ + protected $middlewarePriority = [ + StartSession::class, + ShareErrorsFromSession::class, + Authenticate::class, + ThrottleRequests::class, + AuthenticateSession::class, + SubstituteBindings::class, + Authorize::class, + ]; +} diff --git a/app/App/Listeners/FlushMediaCache.php b/app/App/Listeners/FlushMediaCache.php new file mode 100644 index 0000000..8837bbf --- /dev/null +++ b/app/App/Listeners/FlushMediaCache.php @@ -0,0 +1,24 @@ +media->model; + + if (method_exists($model, 'flushCache')) { + /* + * PHPStan give error: Cannot call method flushCache() on class-string|object. + * But flushCache() is never called if it wouldn't exist, so PHPStan is wrong in this case. + * @phpstan-ignore-next-line + */ + $model->flushCache(); + } + } +} diff --git a/app/App/Listeners/ListenForActivityLogs.php b/app/App/Listeners/ListenForActivityLogs.php new file mode 100644 index 0000000..158a54d --- /dev/null +++ b/app/App/Listeners/ListenForActivityLogs.php @@ -0,0 +1,30 @@ +subject(), + $event->description(), + $event->causer(), + $event->payload() + ); + } + + public function subscribe(Dispatcher $events) : void + { + $events->listen( + LogsActivity::class, + static::class.'@handle' + ); + } +} diff --git a/app/App/Providers/AppServiceProvider.php b/app/App/Providers/AppServiceProvider.php new file mode 100644 index 0000000..fd0da20 --- /dev/null +++ b/app/App/Providers/AppServiceProvider.php @@ -0,0 +1,100 @@ +app->isLocal()) { + $this->app->register(DuskServiceProvider::class); + } + } + + public function boot(): void + { + $this->app->bind(SecureShellKeyGenerator::class, fn () => new SecureShellKey()); + + $this->app->bind(ShellProcessRunnerContract::class, fn () => new ShellProcessRunner()); + + User::observe(UserObserver::class); + + $this->registerDataBags(); + + VerifyEmail::toMailUsing(function ($notifiable, $url) { + return (new MailMessage()) + ->subject($subject = trans('auth.verify.page_header')) + ->view('mails.email-verification', [ + 'url' => $url, + 'subject' => $subject, + ]); + }); + + ResetPassword::toMailUsing(function ($notifiable, $token) { + return (new MailMessage()) + ->subject($subject = trans('auth.passwords.email.page_header')) + ->view('mails.reset-password', [ + 'url' => route('password.reset', ['token' => $token, 'email' => $notifiable->email]), + 'subject' => $subject, + ]); + }); + } + + private function registerDataBags(): void + { + DataBag::register('fortify-content', [ + 'register' => [ + 'pageTitle' => trans('actions.sign_up'), + 'title' => trans('actions.sign_up'), + 'description' => trans('pages.auth.subtitle'), + ], + 'login' => [ + 'pageTitle' => trans('actions.login'), + 'title' => trans('actions.login'), + 'description' => trans('pages.auth.subtitle'), + ], + 'password' => [ + 'reset' => [ + 'pageTitle' => trans('actions.reset_password'), + 'title' => trans('auth.passwords.reset.title'), + 'description' => trans('auth.passwords.reset.description'), + ], + 'request' => [ + 'pageTitle' => trans('actions.reset_password'), + 'title' => trans('auth.passwords.reset.title'), + 'description' => trans('auth.passwords.reset.description'), + ], + ], + 'verification' => [ + 'notice' => [ + 'pageTitle' => trans('auth.verify.page_header'), + ], + 'verify' => [ + 'pageTitle' => trans('auth.verify.page_header'), + ], + 'send' => [ + 'pageTitle' => trans('auth.token.page_header'), + ], + ], + 'two-factor' => [ + 'login' => [ + 'pageTitle' => trans('auth.token.page_header'), + ], + ], + ]); + } +} diff --git a/app/App/Providers/AuthServiceProvider.php b/app/App/Providers/AuthServiceProvider.php new file mode 100644 index 0000000..ed2e7e9 --- /dev/null +++ b/app/App/Providers/AuthServiceProvider.php @@ -0,0 +1,30 @@ + SecureShellKeyPolicy::class, + Server::class => ServerPolicy::class, + ServerProvider::class => ServerProviderPolicy::class, + Token::class => TokenPolicy::class, + ]; + + public function boot(): void + { + $this->registerPolicies(); + } +} diff --git a/app/App/Providers/BroadcastServiceProvider.php b/app/App/Providers/BroadcastServiceProvider.php new file mode 100644 index 0000000..0ff95a6 --- /dev/null +++ b/app/App/Providers/BroadcastServiceProvider.php @@ -0,0 +1,21 @@ + [ + SendEmailVerificationNotification::class, + ], + MediaHasBeenAdded::class => [ + FlushMediaCache::class, + ], + + // Tokens + TokenCreated::class => [ + CreateDefaultNetworks::class, + ], + TokenDeleted::class => [ + PurgeTokenResources::class, + RemoveTokenNotifications::class, + NotifyCollaborators::class, + ], + + // Networks + NetworkCreated::class => [ + // + ], + + // Servers + ServerCreated::class => [ + CreateServerOnProvider::class, + ], + ServerDeleted::class => [ + NotifyUsersOfServerDeletion::class, + DestroyServerOnServerProvider::class, + ], + ServerUpdating::class => [ + UpdateServerProviderName::class, + ], + + // Server Providers + ServerProviderCreated::class => [ + // + ], + ServerProviderDeleted::class => [ + ForgetServerProviderTokenConfiguration::class, + TriggerSecureShellKeyRemovalFromServerProvider::class, + ], + ServerProviderUpdated::class => [ + IndexServerProviderRelatedData::class, + ], + ]; + + /** + * The subscriber classes to register. + * + * @var array + */ + protected $subscribe = [ + ListenForActivityLogs::class, + ]; +} diff --git a/app/App/Providers/HorizonServiceProvider.php b/app/App/Providers/HorizonServiceProvider.php new file mode 100644 index 0000000..0e4a8bc --- /dev/null +++ b/app/App/Providers/HorizonServiceProvider.php @@ -0,0 +1,26 @@ +configureRateLimiting(); + + // Because we register a Token model in a custom namespace, we'll register a Route binding to resolve the model when `{token}` is passed as a parameter... + // However, Laravel Fortify specifies `{token}` attribute for password reset routes, which is a direct collision with our implementation, + // so we to dynamically bind the value. + Route::bind('token', function ($value) { + // Password Reset Token is usually 64 chars... + if (strlen($value) >= 64) { + return $value; + } + + return (new Token())->resolveRouteBinding($value); + }); + + $this->routes(function (): void { + $this->mapApiRoutes(); + + $this->mapWebRoutes(); + }); + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + */ + private function mapWebRoutes(): void + { + Route::middleware('web') + ->group(base_path('routes/web.php')); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + */ + private function mapApiRoutes(): void + { + Route::prefix('api') + ->middleware('api') + ->group(base_path('routes/api.php')); + } + + /** + * Configure the rate limiters for the application. + * + * @return void + */ + private function configureRateLimiting(): void + { + RateLimiter::for('api', function (Request $request): Limit { + return Limit::perMinute(60); + }); + } +} diff --git a/app/App/Providers/ViewServiceProvider.php b/app/App/Providers/ViewServiceProvider.php new file mode 100644 index 0000000..73af744 --- /dev/null +++ b/app/App/Providers/ViewServiceProvider.php @@ -0,0 +1,42 @@ +with('currentUser', Auth::user()); + }); + + View::composer('hermes::navbar-notifications', function ($view): void { + $view->with('notificationCount', Auth::user()?->notifications()->count()); + }); + + View::composer('components.pending-invitations', function ($view): void { + $view->with('invitationsCount', Auth::user()?->invitations()->count()); + }); + } +} diff --git a/app/App/SecureShell/Components/CreateSecureShellKey.php b/app/App/SecureShell/Components/CreateSecureShellKey.php new file mode 100644 index 0000000..19c46f5 --- /dev/null +++ b/app/App/SecureShell/Components/CreateSecureShellKey.php @@ -0,0 +1,49 @@ +validate([ + 'name' => [ + 'required', + 'max:255', + Rule::unique('secure_shell_keys', 'name')->where('user_id', Auth::id()), + ], + 'public_key' => [ + 'required', + new SecureShellKey(), + Rule::unique('secure_shell_keys', 'public_key')->where('user_id', Auth::id()), + ], + ]); + + $this->user->secureShellKeys()->create($data); + + $this->toast(trans('pages.user-settings.create_ssh_success'), 'success'); + + $this->name = null; + $this->public_key = null; + + $this->emit('refreshSecureShellKeys'); + } +} diff --git a/app/App/SecureShell/Components/DeleteSecureShellKey.php b/app/App/SecureShell/Components/DeleteSecureShellKey.php new file mode 100644 index 0000000..cb9bf16 --- /dev/null +++ b/app/App/SecureShell/Components/DeleteSecureShellKey.php @@ -0,0 +1,51 @@ + 'askForConfirmation']; + + public function askForConfirmation(int $id): void + { + $this->keyId = $id; + } + + public function destroy(): void + { + $secureShellKey = $this->user->secureShellKeys()->findOrFail($this->keyId); + + $secureShellKey->delete(); + + $this->toast(trans('pages.user-settings.delete_ssh_success'), 'success'); + + $this->modalClosed(); + + $this->reset(); + + $this->emit('refreshSecureShellKeys'); + } + + public function cancel(): void + { + $this->keyId = null; + + $this->modalClosed(); + } +} diff --git a/app/App/SecureShell/Jobs/AddSecureShellKeyToServerProvider.php b/app/App/SecureShell/Jobs/AddSecureShellKeyToServerProvider.php new file mode 100644 index 0000000..f735afb --- /dev/null +++ b/app/App/SecureShell/Jobs/AddSecureShellKeyToServerProvider.php @@ -0,0 +1,81 @@ +serverProvider->token->keypair; + + $key = $this->serverProvider->client()->createSecureShellKey( + $this->serverProvider->token->slug.'-'.strtolower(Str::random(8)), + $keypair['publicKey'] + ); + + $this->serverProvider->update(['provider_key_id' => $key->id]); + + ServerProviderUpdated::dispatch($this->serverProvider); + } + + public function failed(Throwable $exception) : void + { + report($exception); + + if ($exception instanceof ServerProviderAuthenticationException) { + $this->notifiables()->each->notify(new ServerProviderAuthenticationFailed($this->serverProvider)); + } elseif ($exception instanceof ServerProviderSecureShellKeyUniqueness) { + $this->notifiables()->each->notify(new ServerProviderSecureShellKeyUniquenessNotification($this->serverProvider)); + } elseif ($exception instanceof ServerProviderSecureShellKeyLimitReached) { + $this->notifiables()->each->notify(new ServerProviderSecureShellKeyLimitReachedNotification($this->serverProvider)); + } else { + $this->notifiables()->each->notify(new ServerProviderSecureShellKeyAdditionFailed($this->serverProvider)); + } + } + + /** + * @return Collection + */ + private function notifiables() : Collection + { + return collect([ + $this->initiator, + $this->serverProvider->user(), + $this->serverProvider->token->user, + ])->filter()->unique('id')->values(); + } +} diff --git a/app/App/SecureShell/Jobs/RemoveSecureShellKeyFromServerProvider.php b/app/App/SecureShell/Jobs/RemoveSecureShellKeyFromServerProvider.php new file mode 100644 index 0000000..e4de9c7 --- /dev/null +++ b/app/App/SecureShell/Jobs/RemoveSecureShellKeyFromServerProvider.php @@ -0,0 +1,71 @@ +serverProvider = ServerProvider::withTrashed()->findOrFail($serverProvider->id); + } + + public function handle(): void + { + /** @var string $providerKeyId */ + $providerKeyId = $this->serverProvider->provider_key_id; + + $this->serverProvider->client()->deleteSecureShellKey( + $providerKeyId + ); + + $this->serverProvider->forceDelete(); + } + + public function failed(Throwable $exception): void + { + $this->serverProvider->forceDelete(); + + report($exception); + + $this->notifiables()->each->notify( + $exception instanceof ServerProviderAuthenticationException + ? new ServerProviderAuthenticationFailed($this->serverProvider) + : new ServerProviderSecureShellKeyRemovalFailed($this->serverProvider) + ); + } + + /** + * @return Collection + */ + private function notifiables() : Collection + { + return collect([ + $this->serverProvider->user(), + $this->serverProvider->token->user, + ])->filter()->unique('id')->values(); + } +} diff --git a/app/App/Server/Components/CreateServer.php b/app/App/Server/Components/CreateServer.php new file mode 100644 index 0000000..1464dc8 --- /dev/null +++ b/app/App/Server/Components/CreateServer.php @@ -0,0 +1,243 @@ + 'selectPreset', + 'setProvider' => 'selectProvider', + ]; + + public function mount(Network $network): void + { + $this->token = $network->token; + $this->network = $network; + $this->selectedProvider = $this->selectedProvider ?? $this->getUniqueProviders()->first(); + + if ($network->servers_count === 0) { + $this->preset = PresetTypeEnum::GENESIS; + } + } + + public function render(): View + { + if ($this->selectedProviderSelectedKey !== null) { + $this->selectedProvider = $this->token->serverProviders()->findOrFail($this->selectedProviderSelectedKey); + } + + $this->selectedProviderType = $this->selectedProvider->type; + + return view('livewire.create-server'); + } + + public function updated(string $field): void + { + $this->validateOnly($field, [ + 'delegatePassphrase' => ['nullable', new BIP39Passphrase()], + 'delegatePassword' => ['nullable', 'alpha_num', 'min:8'], + ]); + } + + public function updatedSelectedProviderSelectedKey(): void + { + $this->plan = null; + $this->region = null; + } + + public function selectPreset(string $preset): void + { + $this->preset = $preset; + } + + public function selectProvider(int $providerId): void + { + $this->plan = null; + $this->region = null; + $this->selectedProviderSelectedKey = null; + + $this->selectedProvider = $this->token->serverProviders()->findOrFail($providerId); + + if ($this->getHasMultipleKeysOnProviderProperty()) { + $this->selectedProviderSelectedKey = $this->selectedProvider->id; + } + } + + public function getHasMultipleKeysOnProviderProperty(): bool + { + return $this->token->serverProviders()->where('type', '=', $this->selectedProvider->type)->count() > 1; + } + + public function getProviderEntriesProperty(): Collection + { + return $this->token->serverProviders()->where('type', '=', $this->selectedProvider->type)->get(); + } + + public function getRegionsProperty(): Collection + { + return $this->selectedProvider->regions; + } + + public function getPlansProperty(): Collection + { + return $this->selectedProvider->plans; + } + + public function getFormattedPlansProperty(): Collection + { + $region = $this->selectedProvider->regions()->findOrFail($this->region); + + // Search by string... + $resultsByString = $this->selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->when($this->preset === PresetTypeEnum::EXPLORER || $this->preset === PresetTypeEnum::GENESIS, fn ($query) => $query->where('cores', '>=', config('deployer.deployment.minimumCores'))) + ->whereJsonContains('regions', [$region->uuid]) + ->get(); + + if ($resultsByString->count() > 0) { + $plans = $resultsByString; + + return $plans; + } + + // Search by integer... + $resultsByNumber = $this->selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->when($this->preset === PresetTypeEnum::EXPLORER || $this->preset === PresetTypeEnum::GENESIS, fn ($query) => $query->where('cores', '>=', config('deployer.deployment.minimumCores'))) + ->whereJsonContains('regions', [(int) $region->uuid]) + ->get(); + + if ($resultsByNumber->count() > 0) { + $plans = $resultsByNumber; + + return $plans; + } + + // Server Provider without regions... + $plans = $this->selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->when($this->preset === PresetTypeEnum::EXPLORER || $this->preset === PresetTypeEnum::GENESIS, fn ($query) => $query->where('cores', '>=', config('deployer.deployment.minimumCores'))) + ->get(); + + return $plans; + } + + public function getPresetsProperty(): array + { + return [ + PresetTypeEnum::SEED, + PresetTypeEnum::RELAY, + PresetTypeEnum::FORGER, + PresetTypeEnum::EXPLORER, + ]; + } + + public function getUniqueProviders(): Collection + { + return $this->token->serverProviders->unique('type'); + } + + public function canSelect(): bool + { + if ($this->selectedProviderSelectedKey !== null && $this->getHasMultipleKeysOnProviderProperty()) { + return true; + } + + if (! $this->getHasMultipleKeysOnProviderProperty()) { + return true; + } + + return false; + } + + public function store(): void + { + $this->authorize('create', [Server::class, $this->token]); + + $this->validate([ + 'serverName' => ['required', 'min:3', 'max:50'], + 'preset' => ['required', Rule::in(['genesis', 'seed', 'relay', 'forger', 'explorer'])], + 'selectedProvider' => 'required', + 'region' => 'required', + 'plan' => 'required', + 'delegatePassphrase' => ['nullable', 'required_with:delegatePassword', new BIP39Passphrase()], + 'delegatePassword' => ['nullable', 'alpha_num', 'min:8'], + ]); + + /** @var ServerProviderImage $serverProviderImage */ + $serverProviderImage = $this->selectedProvider->images()->where('uuid', $this->selectedProvider->client()->getImageId())->first(); + + $server = $this->network->servers()->create([ + 'server_provider_id' => $this->selectedProvider->id, + 'name' => Format::withToken($this->serverName), + 'server_provider_region_id' => $this->selectedProvider->regions()->findOrFail($this->region)->id, + 'server_provider_plan_id' => $this->selectedProvider->plans()->findOrFail($this->plan)->id, + 'server_provider_image_id' => $serverProviderImage->id, + 'preset' => $this->preset, + 'delegate_passphrase' => $this->delegatePassphrase, + 'delegate_password' => $this->delegatePassword, + ]); + + /** @var User $user */ + $user = $this->user; + + $server->setMetaAttribute(ServerAttributeEnum::DISCLAIMER_MODAL_SEEN, false); + $server->setMetaAttribute(ServerAttributeEnum::SERVER_CREATED_MODAL_SEEN, false); + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + ServerCreated::dispatch($server); + + $this->redirect($server->pathShow()); + } + + public function cancel(): void + { + $this->redirectRoute('tokens'); + } +} diff --git a/app/App/Server/Components/DeleteServer.php b/app/App/Server/Components/DeleteServer.php new file mode 100644 index 0000000..85d8ed9 --- /dev/null +++ b/app/App/Server/Components/DeleteServer.php @@ -0,0 +1,77 @@ + 'askForConfirmation', + 'setNetwork' => 'setNetwork', + 'setToken' => 'setToken', + ]; + + public function mount(Token $token, Network $network): void + { + $this->token = $token; + $this->network = $network; + } + + public function askForConfirmation(int $id): void + { + $this->serverId = $id; + } + + public function setToken(int $id): void + { + $this->token = Token::findOrFail($id); + $this->network = $this->token->networks()->where('name', NetworkTypeEnum::MAINNET)->firstOrFail(); + } + + public function setNetwork(int $id): void + { + $this->network = $this->token->networks()->where('id', $id)->firstOrFail(); + } + + public function destroy(): void + { + $server = $this->network->servers()->findOrFail($this->serverId); + + $this->authorize('delete', $server); + + $server->delete(); + + $this->serverId = null; + + $this->modalClosed(); + + $this->redirect(url()->previous()); + } + + public function cancel(): void + { + $this->serverId = null; + + $this->modalClosed(); + } +} diff --git a/app/App/Server/Components/DeleteServerProvider.php b/app/App/Server/Components/DeleteServerProvider.php new file mode 100644 index 0000000..4dc182b --- /dev/null +++ b/app/App/Server/Components/DeleteServerProvider.php @@ -0,0 +1,71 @@ + 'askForConfirmation']; + + public function askForConfirmation(int $id): void + { + $this->serverProviderId = $id; + + $this->openModal(); + } + + public function toggleDeleteOnProvider(): void + { + $this->deleteOnProvider = ! $this->deleteOnProvider; + } + + public function destroy() : void + { + $serverProvider = ServerProvider::findOrFail($this->serverProviderId); + + $this->authorize('delete', $serverProvider); + + if ($this->deleteOnProvider && $serverProvider->servers_count > 0) { + $serverProvider->servers()->get()->each->delete(); + } + + $serverProvider->delete(); + + ServerProviderDeleted::dispatch($serverProvider); + + $this->serverProviderId = null; + + $this->closeModal(); + + $this->toast(trans('tokens.server-providers.removed_success')); + $this->emit('refreshServerProviders'); + } + + public function cancel(): void + { + $this->serverProviderId = null; + + $this->closeModal(); + } +} diff --git a/app/App/Server/Components/ManageServerConfiguration.php b/app/App/Server/Components/ManageServerConfiguration.php new file mode 100644 index 0000000..a9b6b05 --- /dev/null +++ b/app/App/Server/Components/ManageServerConfiguration.php @@ -0,0 +1,213 @@ + 'selectProvider', + ]; + + public function mount(Token $token): void + { + $this->token = $token; + $this->selectedProvider = $this->selectedProvider ?? $this->getUniqueProviders()->first(); + + if ($this->token->hasServerProviders() && ! $token->needsServerConfiguration()) { + $serverConfig = $token->getMetaAttribute(ServerAttributeEnum::SERVER_CONFIG); + + $this->selectedProvider = ServerProvider::where('id', $serverConfig['server_provider_id'])->firstOrFail(); + $this->selectedProviderType = $this->selectedProvider->type; + $this->selectedProviderSelectedKey = $this->selectedProvider->id; + $this->serverName = $serverConfig['name']; + $this->region = $serverConfig['server_provider_region_id']; + $this->plan = $serverConfig['server_provider_plan_id']; + } + } + + public function render(): View + { + if ($this->selectedProviderSelectedKey !== null) { + $this->selectedProvider = $this->token->serverProviders()->findOrFail($this->selectedProviderSelectedKey); + } + + if ($this->selectedProvider !== null) { + $this->selectedProviderType = $this->selectedProvider->type; + } + + return view('livewire.manage-server-configuration', [ + 'selectProvider' => $this->selectedProvider, + 'selectedProviderSelectedKey' => $this->selectedProviderSelectedKey, + ]); + } + + public function updatedSelectedProviderSelectedKey(): void + { + $this->plan = null; + $this->region = null; + } + + public function getHasMultipleKeysOnProviderProperty(): bool + { + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + return $this->token->serverProviders()->where('type', '=', $selectedProvider->type)->count() > 1; + } + + public function getProviderEntriesProperty(): Collection + { + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + return $this->token->serverProviders()->where('type', '=', $selectedProvider->type)->get(); + } + + public function getRegionsProperty(): Collection + { + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + return $selectedProvider->regions; + } + + public function getPlansProperty(): Collection + { + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + return $selectedProvider->plans; + } + + public function getFormattedPlansProperty(): Collection + { + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + $region = $selectedProvider->regions()->findOrFail($this->region); + + // Search by string... + $resultsByString = $selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->whereJsonContains('regions', [$region->uuid]) + ->get(); + + if ($resultsByString->count() > 0) { + $plans = $resultsByString; + + return $plans; + } + + // Search by integer... + $resultsByNumber = $selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->whereJsonContains('regions', [(int) $region->uuid]) + ->get(); + + if ($resultsByNumber->count() > 0) { + $plans = $resultsByNumber; + + return $plans; + } + + // Server Provider without regions... + $plans = $selectedProvider->plans() + ->where('memory', '>=', config('deployer.deployment.minimumServerRam')) + ->get(); + + return $plans; + } + + public function selectProvider(int $providerId): void + { + $this->selectedProviderSelectedKey = null; + + $this->selectedProvider = $this->token->serverProviders()->findOrFail($providerId); + + $this->plan = null; + $this->region = null; + } + + public function getUniqueProviders(): Collection + { + return $this->token->serverProviders->unique('type'); + } + + public function canSelect(): bool + { + if ($this->getHasMultipleKeysOnProviderProperty() && $this->selectedProviderSelectedKey !== null) { + return true; + } + + if (! $this->getHasMultipleKeysOnProviderProperty() && $this->selectedProvider !== null) { + return true; + } + + return false; + } + + public function canSubmit(): bool + { + return $this->serverName !== null && + $this->serverName !== '' && + $this->selectedProvider !== null && + $this->region !== null && + $this->plan !== null; + } + + public function store(): void + { + $this->validate([ + 'serverName' => ['required', 'min:3', 'max:50'], + 'selectedProvider' => 'required', + 'selectedProviderSelectedKey' => Rule::requiredIf($this->getHasMultipleKeysOnProviderProperty()), + 'region' => 'required', + 'plan' => 'required', + ]); + + /** @var ServerProvider $selectedProvider */ + $selectedProvider = $this->selectedProvider; + + /** @var string $serverName */ + $serverName = $this->serverName; + + $this->token->setMetaAttribute(ServerAttributeEnum::SERVER_CONFIG, [ + 'server_provider_id' => $selectedProvider->id, + 'name' => $serverName, + 'server_provider_region_id' => $selectedProvider->regions()->findOrFail($this->region)->id, + 'server_provider_plan_id' => $selectedProvider->plans()->findOrFail($this->plan)->id, + ]); + + $this->redirectRoute('tokens.show', ['token' => $this->token]); + } + + public function cancel(): void + { + $this->redirectRoute('tokens.show', ['token' => $this->token]); + } +} diff --git a/app/App/Server/Components/ManageServerProviders.php b/app/App/Server/Components/ManageServerProviders.php new file mode 100644 index 0000000..8f00067 --- /dev/null +++ b/app/App/Server/Components/ManageServerProviders.php @@ -0,0 +1,138 @@ + 'selectProvider', + 'refreshServerProviders' => '$refresh', + ]; + + public function mount(Token $token): void + { + $this->token = $token; + $this->providers = $token->serverProviders; + $this->isSubmittingFirstProvider = false; + $this->provider = ServerProviderTypeEnum::DIGITALOCEAN; + } + + public function render(): View + { + return view('livewire.manage-server-providers', ['token' => $this->token, 'providers' => $this->providers, 'selectedProvider' => $this->provider]); + } + + public function selectProvider(string $provider): void + { + $this->provider = $provider; + } + + public function store(): void + { + $this->authorize('create', [ServerProvider::class, $this->token]); + + $this->validate([ + 'name' => ['required', 'max:255', Rule::unique('server_providers', 'name')->where('token_id', $this->token->id)], + 'access_token' => ['required', 'max:255', new UniqueTokenExtraAttribute($this->token)], + 'access_key' => ['required_if:type,===,aws', new UniqueTokenExtraAttribute($this->token)], + ]); + + if (! $this->token->onboarding()->completed(TokenOnboardingStatusEnum::SERVER_PROVIDERS)) { + $this->isSubmittingFirstProvider = true; + + $this->dispatchBrowserEvent('pending-first-provider', true); + } + + $serverProvider = new ServerProvider(); + $serverProvider->type = $this->provider; + $serverProvider->extra_attributes->set([ServerAttributeEnum::ACCESS_TOKEN => $this->access_token]); + + if ($serverProvider->client()->valid()) { + /** @var User $user */ + $user = $this->user; + + $serverProvider = $this->token->serverProviders()->create([ + 'name' => $this->name, + 'type' => $this->provider, + ]); + + $serverProvider->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + $serverProvider->setMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN, $this->access_token); + $serverProvider->setMetaAttribute(ServerAttributeEnum::ACCESS_KEY, $this->access_key); + + if ($this->hasRegisteredProviderOfSameType($serverProvider->type)) { + $serverProvider->update(['provider_key_id' => $this->providers->where('type', '=', $serverProvider->type)->first()->provider_key_id]); + } else { + AddSecureShellKeyToServerProvider::dispatch($serverProvider, $user); + } + + IndexServerProviderPlans::dispatch($serverProvider); + IndexServerProviderRegions::dispatch($serverProvider); + IndexServerProviderImages::dispatch($serverProvider); + + $this->providers->push($serverProvider); + + ServerProviderCreated::dispatch($serverProvider); + + if (count($this->providers) === 1) { + alert('tokens.server-providers.added_success_redirect', FlashType::SUCCESS); + } else { + alert('tokens.server-providers.added_success', FlashType::SUCCESS); + } + } else { + if (! $this->token->hasServerProviders()) { + $this->isSubmittingFirstProvider = false; + + $this->dispatchBrowserEvent('pending-first-provider', false); + } + alert('tokens.server-providers.added_failed', FlashType::ERROR); + } + } + + private function hasRegisteredProviderOfSameType(string $type): bool + { + return $this->token->serverProviders()->where('type', $type)->count() > 1; + } +} diff --git a/app/App/Server/Components/RedirectOnServerProviderCompletion.php b/app/App/Server/Components/RedirectOnServerProviderCompletion.php new file mode 100644 index 0000000..38f6c99 --- /dev/null +++ b/app/App/Server/Components/RedirectOnServerProviderCompletion.php @@ -0,0 +1,29 @@ +token = $token; + } + + public function render(): View + { + if ($this->token->onboarding()->completed(TokenOnboardingStatusEnum::SERVER_PROVIDERS) && $this->token->serverProviders()->whereNull('provider_key_id')->count() === 0) { + redirect()->to(route('tokens.show', $this->token)); + } + + return view('livewire.redirect-on-server-provider-completion', ['token' => $this->token]); + } +} diff --git a/app/App/Server/Components/RenameServer.php b/app/App/Server/Components/RenameServer.php new file mode 100644 index 0000000..d65c33a --- /dev/null +++ b/app/App/Server/Components/RenameServer.php @@ -0,0 +1,137 @@ + 'renameServer', + ]; + + public function mount(Token $token, Network $network): void + { + $this->token = $token; + $this->network = $network; + } + + public function updated(string $propertyName): void + { + $this->validateOnly($propertyName, [ + 'name' => [ + 'required', + $this->getNameValidator(), + ], + ]); + } + + public function renameServer(int $id): void + { + $this->serverId = $id; + + /** @var Server $server */ + $server = $this->network->servers()->findOrFail($this->serverId); + + $this->server = $server; + $this->name = $this->server->name; + + $this->nameValidator = $this->server->serverProvider->client()::nameValidator(); + } + + public function rename(): void + { + $this->validate([ + 'name' => [ + 'required', + $this->getNameValidator(), + ], + ]); + + $server = $this->network->servers()->findOrFail($this->serverId); + + $this->authorize('rename', $server); + + try { + $server->update(['name' => $this->name]); + } catch (Throwable $e) { + $this->handleException($e, $server, fn ($message) => throw ValidationException::withMessages([ + 'name' => [$message], + ])); + } + + $this->serverId = null; + $this->server = null; + $this->name = null; + $this->nameValidator = ''; + + $this->closeModal(); + + $this->redirect(route('tokens', request()->query())); + } + + public function cancel(): void + { + $this->serverId = null; + $this->server = null; + $this->name = null; + $this->nameValidator = ''; + $this->resetErrorBag(); + + $this->closeModal(); + } + + private function getNameValidator(): Rule + { + return App::make($this->nameValidator); + } + + private function handleException(Throwable $exception, Server $server, Closure $fail) : void + { + if ($exception instanceof ServerNotFound) { + $fail(trans('notifications.server_not_found', ['server' => $server->getOriginal('name')])); + } elseif ($exception instanceof ServerProviderAuthenticationException) { + $fail(trans('notifications.server_provider_authentication_error', [ + 'provider' => ServerProviderTypeEnum::label($server->serverProvider->type), + 'name' => $server->serverProvider->name, + ])); + } else { + report($exception); + + $fail(trans('notifications.something_went_wrong')); + } + } +} diff --git a/app/App/Server/Components/ServerDeploymentTracker.php b/app/App/Server/Components/ServerDeploymentTracker.php new file mode 100644 index 0000000..078fc47 --- /dev/null +++ b/app/App/Server/Components/ServerDeploymentTracker.php @@ -0,0 +1,181 @@ +token = $token; + $this->serverId = $serverId; + $this->statuses = collect([]); + + // Might be weird to see the method called inline here, but it's called just to + // set up any additional state that might be set up if the server is missing... + $this->server(); + } + + public function render() : View + { + // Wraps into `optional()` so Blade template can chain calls that will not throw an exception if server is not found... + $server = optional($this->server()); + + return view('livewire.server-deployment-tracker', [ + 'server' => $server, + 'hasFinalState' => $server->isProvisioned() || $server->isFailed(), + 'userCanManageServer' => $this->userCanManageServer(), + ]); + } + + public function getGroupsProperty() : array + { + $server = $this->server(); + + if ($server === null || count($this->cachedGroups) > 0) { + return $this->cachedGroups; + } + + $this->cachedGroups = (new ServerDeploymentStatus())->getGroupStates()[$server->preset]; + + return $this->cachedGroups; + } + + public function getFirstState() : string + { + $server = $this->server(); + + if ($server === null) { + return head(head($this->cachedGroups)); + } + + $states = (new ServerDeploymentStatus())->getGroupStates()[$server->preset]; + + return head(head($states)); + } + + public function closeDisclaimerModal() : void + { + abort_unless($this->userCanManageServer(), 403); + + optional($this->server())->setMetaAttribute(ServerAttributeEnum::DISCLAIMER_MODAL_SEEN, true); + + $this->closeModal(); + } + + public function closeServerCreatedModal() : void + { + optional($this->server())->setMetaAttribute(ServerAttributeEnum::SERVER_CREATED_MODAL_SEEN, true); + + $this->closeModal(); + } + + public function getCredentials() : string + { + abort_unless($this->userCanManageServer(), 403); + + $usernameKey = trans('pages.server.installation.passwords_modal.username'); + $userPasswordKey = trans('pages.server.installation.passwords_modal.user_password'); + $sudoPasswordKey = trans('pages.server.installation.passwords_modal.sudo_password'); + + $server = $this->server(); + + if ($server === null) { + return ''; + } + + return + "{$usernameKey}: {$server->token->normalized_token}".'\n'. + "{$userPasswordKey}: {$server->user_password}".'\n'. + "{$sudoPasswordKey}: {$server->sudo_password}"; + } + + public function hasEverHadStatus(string $status) : bool + { + return $this->statuses->where('name', $status)->isNotEmpty(); + } + + private function userCanManageServer() : bool + { + /** @var User */ + $user = $this->user; + + $server = $this->server(); + + // If server is deleted, we "fake" that user has a permission to create servers just so Livewire doesn't show 403 modal... + // All credentials are still hidden from the user... + if ($server === null) { + return true; + } + + return $user->can('create', [ + Server::class, $server->token, + ]); + } + + private function server() : ?Server + { + if ($this->server !== null) { + return $this->server; + } + + /** @var Server|null $server */ + $server = $this->token->servers()->find($this->serverId); + + $this->server = $server; + + if ($this->server === null) { + $this->showDeploymentFailedModal = true; + $this->failureReason = trans('pages.server.installation.failed_modal.generic_error'); + + return null; + } + + if ($this->server->isFailed()) { + $this->showDeploymentFailedModal = true; + $this->failureReason = (string) $this->server->latestStatus(); + } + + $this->server->load('statuses'); + + $this->preset = $this->server->preset; + $this->currentStatus = $this->server->status(); + $this->statuses = $this->server->statuses; + + return $this->server; + } +} diff --git a/app/App/Server/Controllers/DeploymentStatusController.php b/app/App/Server/Controllers/DeploymentStatusController.php new file mode 100644 index 0000000..732d650 --- /dev/null +++ b/app/App/Server/Controllers/DeploymentStatusController.php @@ -0,0 +1,58 @@ +filled('version')) { + $status = $request->input('status'); + + $statuses = $this->getAllDeploymentStatuses(); + if (in_array($status, $statuses, true)) { + $server->setStatus($status); + } + + if (Str::startsWith($status, 'failed')) { + $this->handleFailedStatus($server, $status); + } + } else { + $server->fill([ + 'core_version' => $request->version, + ])->save(); + } + + // If any changes to any server happen we want to flush the token cache + // to ensure that checks like deployments of certain types run against + // fresh data to avoid data corruption or outdated UI feedback for users. + $server->token->flushCache(); + + return response()->noContent(); + } + + public function getAllDeploymentStatuses() : array + { + $serverDeploymentStatus = new ReflectionClass(new ServerDeploymentStatus()); + + return $serverDeploymentStatus->getConstants(); + } + + private function handleFailedStatus(Server $server, string $status): void + { + Log::warning('Missing case for failed deployment status: "'.$status.'"'); + + $server->setStatus('failed'); + } +} diff --git a/app/App/Server/Jobs/CreateServerOnProvider.php b/app/App/Server/Jobs/CreateServerOnProvider.php new file mode 100644 index 0000000..b63f47b --- /dev/null +++ b/app/App/Server/Jobs/CreateServerOnProvider.php @@ -0,0 +1,80 @@ +server->serverProvider->client()->create($this->server); + + $this->server->update([ + 'provider_server_id' => $remoteServer->id, + 'ip_address' => $remoteServer->remoteAddress, + ]); + + ServerProvisioner::dispatch($this->server); + + $this->notifiables( + notifyProviderOwner: false + )->each->notify(new ServerDeployed($this->server)); + } + + public function failed(Throwable $exception) : void + { + report($exception); + + // Server was actually created on the provider... + if ($this->server->provider_server_id !== null) { + $this->server->setStatus('failed'); + + return; + } + + $this->notifiables(notifyProviderOwner: true)->each->notify( + $exception instanceof ServerLimitExceeded + ? new RemoteServerLimitReached($this->server->serverProvider) + : new ServerFailedToCreateOnProvider($this->server->serverProvider, $this->server->name) + ); + + $this->server->delete(); + } + + /** + * @return Collection + */ + private function notifiables(bool $notifyProviderOwner) : Collection + { + return collect([ + $this->server->creator(), + $this->server->token->user, + $notifyProviderOwner ? $this->server->serverProvider->user() : null, + ])->filter()->unique('id')->values(); + } +} diff --git a/app/App/Server/Jobs/DestroyServerOnServerProvider.php b/app/App/Server/Jobs/DestroyServerOnServerProvider.php new file mode 100644 index 0000000..3c60050 --- /dev/null +++ b/app/App/Server/Jobs/DestroyServerOnServerProvider.php @@ -0,0 +1,55 @@ +serverProviderClient->delete($this->providerServerId); + } + + public function failed(Throwable $exception) : void + { + report($exception); + + $this->notifiables()->each->notify( + new ServerProviderServerRemovalFailed($this->server->serverProvider) + ); + } + + /** + * @return Collection + */ + private function notifiables() : Collection + { + return collect([ + $this->server->creator(), + $this->server->token->user, + $this->server->serverProvider->user(), + ])->filter()->unique('id')->values(); + } +} diff --git a/app/App/Server/Jobs/IndexServerProviderImages.php b/app/App/Server/Jobs/IndexServerProviderImages.php new file mode 100644 index 0000000..529a87d --- /dev/null +++ b/app/App/Server/Jobs/IndexServerProviderImages.php @@ -0,0 +1,57 @@ +serverProvider->client()->images()->items; + + DB::transaction(function () use ($images) { + $serverProviderImages = $images->map(fn ($image) => ServerProviderImage::updateOrCreate(['uuid' => $image->id], [ + 'uuid' => $image->id, + 'name' => $image->name, + ])); + + $this->serverProvider->images()->sync($serverProviderImages->pluck('id')->unique()); + }, 5); + } + + public function failed(): void + { + $this->serverProvider->token->user->notify(new IndexServerProviderImagesFailed($this->serverProvider)); + + $serverProviderOwner = $this->serverProvider->user(); + + if ($serverProviderOwner !== null && $serverProviderOwner->isNot($this->serverProvider->token->user) && $this->serverProvider->token->hasCollaborator($serverProviderOwner)) { + $serverProviderOwner->notify(new IndexServerProviderImagesFailed($this->serverProvider)); + } + } + + public function tags(): array + { + return ['images', 'serverProvider:'.$this->serverProvider->id]; + } +} diff --git a/app/App/Server/Jobs/IndexServerProviderPlans.php b/app/App/Server/Jobs/IndexServerProviderPlans.php new file mode 100644 index 0000000..0eea412 --- /dev/null +++ b/app/App/Server/Jobs/IndexServerProviderPlans.php @@ -0,0 +1,60 @@ +serverProvider->client()->plans()->items; + + DB::transaction(function () use ($plans) { + $serverProviderPlans = $plans->map(fn ($plan) => ServerProviderPlan::updateOrCreate(['uuid' => $plan->id], [ + 'uuid' => $plan->id, + 'disk' => $plan->disk, + 'memory' => $plan->memory, + 'cores' => $plan->cores, + 'regions' => $plan->regions, + ])); + + $this->serverProvider->plans()->sync($serverProviderPlans->pluck('id')->unique()); + }, 5); + } + + public function failed(): void + { + $this->serverProvider->token->user->notify(new IndexServerProviderPlansFailed($this->serverProvider)); + + $serverProviderOwner = $this->serverProvider->user(); + + if ($serverProviderOwner !== null && $serverProviderOwner->isNot($this->serverProvider->token->user) && $this->serverProvider->token->hasCollaborator($serverProviderOwner)) { + $serverProviderOwner->notify(new IndexServerProviderPlansFailed($this->serverProvider)); + } + } + + public function tags(): array + { + return ['plans', 'serverProvider:'.$this->serverProvider->id]; + } +} diff --git a/app/App/Server/Jobs/IndexServerProviderRegions.php b/app/App/Server/Jobs/IndexServerProviderRegions.php new file mode 100644 index 0000000..0b11cc0 --- /dev/null +++ b/app/App/Server/Jobs/IndexServerProviderRegions.php @@ -0,0 +1,57 @@ +serverProvider->client()->regions()->items; + + DB::transaction(function () use ($regions) { + $serverProviderRegions = $regions->map(fn ($region) => ServerProviderRegion::updateOrCreate(['uuid' => $region->id], [ + 'uuid' => $region->id, + 'name' => $region->name, + ])); + + $this->serverProvider->regions()->sync($serverProviderRegions->pluck('id')->unique()); + }, 5); + } + + public function failed(): void + { + $this->serverProvider->token->user->notify(new IndexServerProviderRegionsFailed($this->serverProvider)); + + $serverProviderOwner = $this->serverProvider->user(); + + if ($serverProviderOwner !== null && $serverProviderOwner->isNot($this->serverProvider->token->user) && $this->serverProvider->token->hasCollaborator($serverProviderOwner)) { + $serverProviderOwner->notify(new IndexServerProviderRegionsFailed($this->serverProvider)); + } + } + + public function tags(): array + { + return ['regions', 'serverProvider:'.$this->serverProvider->id]; + } +} diff --git a/app/App/Server/Jobs/ProvisionServer.php b/app/App/Server/Jobs/ProvisionServer.php new file mode 100644 index 0000000..283bf89 --- /dev/null +++ b/app/App/Server/Jobs/ProvisionServer.php @@ -0,0 +1,62 @@ + ProvisionExplorer::class, + 'forger' => ProvisionForger::class, + 'genesis' => ProvisionGenesis::class, + 'relay' => ProvisionRelay::class, + 'seed' => ProvisionSeed::class, + ]; + + public function __construct(public Server $server) + { + } + + public function handle(): void + { + /** @var ProvisionRelay $script */ + $script = new $this->presets[$this->server->preset]($this->server); + + $task = $this->server->addTask($script)->run(); + + if (! $task->isSuccessful()) { + throw new Exception($task->output); + } + + RemovePasswordsFromServer::dispatch($this->server); + + $this->server + ->token + ->collaborators + ->each + ->notify(new ServerProvisioned($this->server)); + } +} diff --git a/app/App/Server/Jobs/ProvisionUser.php b/app/App/Server/Jobs/ProvisionUser.php new file mode 100644 index 0000000..d45d661 --- /dev/null +++ b/app/App/Server/Jobs/ProvisionUser.php @@ -0,0 +1,44 @@ +server->addTask(new Script($this->server))->run(); + + if ($task->isSuccessful()) { + ProvisionServer::dispatch($this->server)->onQueue('long-running-queue'); + } else { + $this->release(10); + } + } + + public function failed(): void + { + $this->server->setStatus('failed'); + } +} diff --git a/app/App/Server/Jobs/RemovePasswordsFromServer.php b/app/App/Server/Jobs/RemovePasswordsFromServer.php new file mode 100644 index 0000000..8b6f805 --- /dev/null +++ b/app/App/Server/Jobs/RemovePasswordsFromServer.php @@ -0,0 +1,36 @@ +server->update([ + 'user_password' => null, + 'sudo_password' => null, + 'delegate_passphrase' => null, + 'delegate_password' => null, + 'provisioned_at' => now(), + ]); + } +} diff --git a/app/App/Server/Jobs/ServerProvisioner.php b/app/App/Server/Jobs/ServerProvisioner.php new file mode 100644 index 0000000..e0d0c09 --- /dev/null +++ b/app/App/Server/Jobs/ServerProvisioner.php @@ -0,0 +1,72 @@ +server->isProvisioned()) { + $this->delete(); + + return null; + } + + // Server has failed to provision within the 30 mins... + if ($this->server->olderThan(minutes: 30)) { + $this->failed(); + + return null; + } + + // Server is still provisioning... + if ($this->server->isProvisioning()) { + $this->release(10); + + return null; + } + + // Server is ready for provisioning when it has an IP address assigned to it... + if ($this->server->isReadyForProvisioning()) { + $this->server->touch('provisioning_job_dispatched_at'); + + return ProvisionUser::dispatch($this->server); + } + + $this->release(10); + + return null; + } + + public function retryUntil() : DateTime + { + return now()->addMinutes(35); + } + + public function failed() : void + { + $this->server->setStatus('failed'); + } +} diff --git a/app/App/Server/Jobs/WaitForServerToStart.php b/app/App/Server/Jobs/WaitForServerToStart.php new file mode 100644 index 0000000..addffc1 --- /dev/null +++ b/app/App/Server/Jobs/WaitForServerToStart.php @@ -0,0 +1,62 @@ +server->isOnline()) { + return; + } + + if ($this->reachable()) { + $this->server->markAsOnline(); + + return; + } + + $this->server->token->collaborators->each->notify(new ServerUnreachable($this->server)); + } + + public function reachable() : bool + { + while ($this->failureCount <= 5) { + $process = new Process(['ping', '-c 3', '-i 5', $this->server->ip_address]); + $process->setTimeout(15); + + $response = ShellProcessRunner::run($process); + + if ($response->exitCode === 0) { + break; + } + + $this->failureCount++; + } + + return $this->failureCount < 3; + } +} diff --git a/app/App/Server/Notifications/IndexServerProviderImagesFailed.php b/app/App/Server/Notifications/IndexServerProviderImagesFailed.php new file mode 100644 index 0000000..24c2e81 --- /dev/null +++ b/app/App/Server/Notifications/IndexServerProviderImagesFailed.php @@ -0,0 +1,38 @@ +token = $this->serverProvider->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.server_provider_image_index_failed', ['serverProvider' => $this->serverProvider->name]), + ]) + ->danger() + ->getContent(); + } +} diff --git a/app/App/Server/Notifications/IndexServerProviderPlansFailed.php b/app/App/Server/Notifications/IndexServerProviderPlansFailed.php new file mode 100644 index 0000000..3d83c60 --- /dev/null +++ b/app/App/Server/Notifications/IndexServerProviderPlansFailed.php @@ -0,0 +1,38 @@ +token = $this->serverProvider->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.server_provider_plan_index_failed', ['serverProvider' => $this->serverProvider->name]), + ]) + ->danger() + ->getContent(); + } +} diff --git a/app/App/Server/Notifications/IndexServerProviderRegionsFailed.php b/app/App/Server/Notifications/IndexServerProviderRegionsFailed.php new file mode 100644 index 0000000..1e5a89d --- /dev/null +++ b/app/App/Server/Notifications/IndexServerProviderRegionsFailed.php @@ -0,0 +1,38 @@ +token = $this->serverProvider->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.server_provider_region_index_failed', ['serverProvider' => $this->serverProvider->name]), + ]) + ->danger() + ->getContent(); + } +} diff --git a/app/App/Server/Notifications/RemoteServerLimitReached.php b/app/App/Server/Notifications/RemoteServerLimitReached.php new file mode 100644 index 0000000..7c2a17f --- /dev/null +++ b/app/App/Server/Notifications/RemoteServerLimitReached.php @@ -0,0 +1,44 @@ +token = $this->serverProvider->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.remote_server_limit_reached', ['serverProvider' => $this->serverProvider->name]), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerDeleted.php b/app/App/Server/Notifications/ServerDeleted.php new file mode 100644 index 0000000..656f63d --- /dev/null +++ b/app/App/Server/Notifications/ServerDeleted.php @@ -0,0 +1,47 @@ +token()->withTrashed()->first(); + + $this->token = $token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServer($this->server, [ + 'content' => trans('notifications.subjects.server_deleted', ['server' => $this->server->name]), + ], $this->token) + ->success() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->token?->hasCollaborator($notifiable) ?? false; + } +} diff --git a/app/App/Server/Notifications/ServerDeployed.php b/app/App/Server/Notifications/ServerDeployed.php new file mode 100644 index 0000000..215337f --- /dev/null +++ b/app/App/Server/Notifications/ServerDeployed.php @@ -0,0 +1,39 @@ +token = $this->server->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServer($this->server, [ + 'content' => trans('notifications.subjects.server_deployed', ['server' => $this->server->name]), + ]) + ->withAction(trans('actions.view'), route('tokens.servers.show', [$this->token, $this->server->network, $this->server])) + ->success() + ->getContent(); + } +} diff --git a/app/App/Server/Notifications/ServerFailedDeployment.php b/app/App/Server/Notifications/ServerFailedDeployment.php new file mode 100644 index 0000000..a39ebfc --- /dev/null +++ b/app/App/Server/Notifications/ServerFailedDeployment.php @@ -0,0 +1,56 @@ +token = $this->server->token; + } + + public function via(): array + { + return ['database', 'mail']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServer($this->server, [ + 'content' => trans('notifications.subjects.server_failed_deployment', ['server' => $this->server->name]), + ]) + ->withAction(trans('actions.view'), route('tokens.servers.show', [$this->token, $this->server->network, $this->server])) + ->danger() + ->getContent(); + } + + public function toMail(): MailMessage + { + return (new MailMessage()) + ->subject($subject = strip_tags(trans('notifications.subjects.server_failed_deployment', ['server' => $this->server->name]))) + ->view('mails.server-failed-deployment', [ + 'subject' => $subject, + 'server' => $this->server, + ]); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->server->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerFailedToCreateOnProvider.php b/app/App/Server/Notifications/ServerFailedToCreateOnProvider.php new file mode 100644 index 0000000..d4d79e3 --- /dev/null +++ b/app/App/Server/Notifications/ServerFailedToCreateOnProvider.php @@ -0,0 +1,56 @@ +serverProvider = $serverProvider; + $this->token = $this->serverProvider->token; + $this->serverName = $serverName; + } + + public function via() : array + { + return ['database']; + } + + public function toArray() : array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.server_failed_to_create', ['server' => $this->serverName, 'provider' => $this->serverProviderLabel()]), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->token->hasCollaborator($notifiable); + } + + private function serverProviderLabel() : string + { + return ServerProviderTypeEnum::label($this->serverProvider->type); + } +} diff --git a/app/App/Server/Notifications/ServerProviderAuthenticationFailed.php b/app/App/Server/Notifications/ServerProviderAuthenticationFailed.php new file mode 100644 index 0000000..0509b77 --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderAuthenticationFailed.php @@ -0,0 +1,47 @@ +token = $serverProvider->token; + } + + public function via(): array + { + return ['database']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServerProvider($this->serverProvider, [ + 'content' => trans( + 'notifications.subjects.server_provider_auth_failed', + ['serverProvider' => $this->serverProvider->name] + ), + ]) + ->warning() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProviderSecureShellKeyAdditionFailed.php b/app/App/Server/Notifications/ServerProviderSecureShellKeyAdditionFailed.php new file mode 100644 index 0000000..523b00d --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderSecureShellKeyAdditionFailed.php @@ -0,0 +1,43 @@ +fromServerProvider($this->serverProvider, [ + 'content' => trans( + 'notifications.subjects.server_provider_ssh_key_addition_failed', + ['serverProvider' => $this->serverProvider->name] + ), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->serverProvider->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProviderSecureShellKeyLimitReached.php b/app/App/Server/Notifications/ServerProviderSecureShellKeyLimitReached.php new file mode 100644 index 0000000..c5bd53c --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderSecureShellKeyLimitReached.php @@ -0,0 +1,43 @@ +fromServerProvider($this->serverProvider, [ + 'content' => trans( + 'notifications.subjects.server_provider_ssh_key_limit_reached', + ['serverProvider' => $this->serverProvider->name] + ), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->serverProvider->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProviderSecureShellKeyRemovalFailed.php b/app/App/Server/Notifications/ServerProviderSecureShellKeyRemovalFailed.php new file mode 100644 index 0000000..c94904e --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderSecureShellKeyRemovalFailed.php @@ -0,0 +1,43 @@ +fromServerProvider($this->serverProvider, [ + 'content' => trans( + 'notifications.subjects.server_provider_ssh_key_removal_failed', + ['serverProvider' => $this->serverProvider->name] + ), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->serverProvider->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProviderSecureShellKeyUniqueness.php b/app/App/Server/Notifications/ServerProviderSecureShellKeyUniqueness.php new file mode 100644 index 0000000..94bf8db --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderSecureShellKeyUniqueness.php @@ -0,0 +1,42 @@ +fromServerProvider($this->serverProvider, [ + 'content' => trans('notifications.subjects.server_provider_ssh_key_uniqueness_error', [ + 'serverProvider' => $this->serverProvider->name, + ]), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->serverProvider->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProviderServerRemovalFailed.php b/app/App/Server/Notifications/ServerProviderServerRemovalFailed.php new file mode 100644 index 0000000..adbc81c --- /dev/null +++ b/app/App/Server/Notifications/ServerProviderServerRemovalFailed.php @@ -0,0 +1,43 @@ +fromServerProvider($this->serverProvider, [ + 'content' => trans( + 'notifications.subjects.server_provider_server_removal_failed', + ['serverProvider' => $this->serverProvider->name] + ), + ]) + ->danger() + ->getContent(); + } + + public function shouldSend(User $notifiable) : bool + { + return $this->serverProvider->token->hasCollaborator($notifiable); + } +} diff --git a/app/App/Server/Notifications/ServerProvisioned.php b/app/App/Server/Notifications/ServerProvisioned.php new file mode 100644 index 0000000..d232c45 --- /dev/null +++ b/app/App/Server/Notifications/ServerProvisioned.php @@ -0,0 +1,60 @@ +token = $server->token; + } + + public function via(): array + { + return ['database', 'mail']; + } + + public function toArray(): array + { + return (new NotificationBuilder()) + ->fromServer($this->server, [ + 'content' => trans('notifications.subjects.server_provisioned', ['server' => $this->server->name]), + ]) + ->withAction(trans('actions.view'), $this->server->pathShow()) + ->success() + ->getContent(); + } + + public function toMail(User $notifiable): MailMessage + { + $userCanCreateServers = $notifiable->can('create', [ + Server::class, $this->token, + ]); + + return (new MailMessage()) + ->subject($subject = strip_tags(trans('notifications.subjects.server_provisioned', ['server' => $this->server->name]))) + ->view('mails.server-provisioned', [ + 'subject' => $subject, + 'token' => $this->token, + 'server' => $this->server, + 'username' => $this->token->normalized_token, + 'userPassword' => $userCanCreateServers ? $this->server->user_password : null, + 'sudoPassword' => $userCanCreateServers ? $this->server->sudo_password : null, + 'userCanCreateServers' => $userCanCreateServers, + ]); + } +} diff --git a/app/App/Server/Notifications/ServerUnreachable.php b/app/App/Server/Notifications/ServerUnreachable.php new file mode 100644 index 0000000..eea3a96 --- /dev/null +++ b/app/App/Server/Notifications/ServerUnreachable.php @@ -0,0 +1,37 @@ +fromServer($this->server, [ + 'content' => trans( + 'notifications.subjects.server_unreachable', + ['server' => $this->server->name] + ), + ]) + ->warning() + ->getContent(); + } +} diff --git a/app/App/Server/Requests/StoreServerProviderRequest.php b/app/App/Server/Requests/StoreServerProviderRequest.php new file mode 100644 index 0000000..d6d7c11 --- /dev/null +++ b/app/App/Server/Requests/StoreServerProviderRequest.php @@ -0,0 +1,25 @@ +check(); + } + + public function rules(): array + { + return [ + 'type' => ['required', 'max:255'], + 'name' => ['required', 'max:255'], + 'access_token' => ['required', 'max:255'], + 'access_key' => 'required_if:type,===,aws', + ]; + } +} diff --git a/app/App/Server/Resources/PlanResource.php b/app/App/Server/Resources/PlanResource.php new file mode 100644 index 0000000..0b34992 --- /dev/null +++ b/app/App/Server/Resources/PlanResource.php @@ -0,0 +1,26 @@ + $this->disk.'GB / '.$this->memory.'MB / '.$this->cores.' Cores', + 'value' => $this->id, + 'memory' => $this->memory, + 'regions' => $this->regions, + ]; + } +} diff --git a/app/App/Server/Resources/RegionResource.php b/app/App/Server/Resources/RegionResource.php new file mode 100644 index 0000000..1ff1ef1 --- /dev/null +++ b/app/App/Server/Resources/RegionResource.php @@ -0,0 +1,24 @@ + $this->name, + 'value' => $this->id, + ]; + } +} diff --git a/app/App/Token/Components/ActiveServers.php b/app/App/Token/Components/ActiveServers.php new file mode 100644 index 0000000..1eab55e --- /dev/null +++ b/app/App/Token/Components/ActiveServers.php @@ -0,0 +1,210 @@ + 'setToken', + 'selectNetwork' => 'selectNetwork', + 'sortingUpdated' => 'sortingUpdated', + ]; + + /** @var mixed */ + protected $queryString = [ + 'network' => ['except' => ''], + ]; + + public function getActiveNetwork(): ?Network + { + $validNetworks = [ + NetworkTypeEnum::MAINNET, + NetworkTypeEnum::DEVNET, + NetworkTypeEnum::TESTNET, + ]; + + if ($this->network !== null && in_array($this->network, $validNetworks, true)) { + return $this->selectedToken->network($this->network); + } + + return $this->selectedToken->network(NetworkTypeEnum::MAINNET); + } + + public function mount(): void + { + $this->setNetwork($this->getActiveNetwork()); + } + + public function render(): View + { + return view('livewire.active-servers', [ + 'selectedToken' => $this->selectedToken, + 'selectedNetwork' => $this->selectedNetwork, + 'selectedNetworkServers' => $this->selectedNetworkServers, + 'filteredNetworkServers' => $this->filteredNetworkServers, + ]); + } + + public function setToken(int $id): void + { + $this->selectedToken = Token::findOrFail($id); + + $this->setNetwork($this->getActiveNetwork()); + } + + public function selectNetwork(int $id): void + { + $network = $this->selectedToken->networks()->findOrFail($id); + + $this->setNetwork($network); + + $this->network = $this->selectedNetwork->name; + + $this->emit('setNetwork', $this->selectedNetwork->id); + } + + public function sortingUpdated(): void + { + if ($this->sortDirection === 'asc') { + /* @phpstan-ignore-next-line */ + $this->selectedNetworkServers = $this->selectedNetworkServers->sortBy($this->sortBy); + } elseif ($this->sortDirection === 'desc') { + $this->selectedNetworkServers = $this->selectedNetworkServers + ->sortByDesc($this->sortBy ?? ''); + } else { + $this->selectedNetworkServers = $this->selectedNetworkServers + ->sortByDesc('created_at'); + } + } + + public function startServer(int $id): void + { + $server = $this->selectedNetwork->servers()->findOrFail($id); + + $this->authorize('start', $server); + + try { + $server->serverProvider->client()->start($server->provider_server_id); + + $server->markAsOnline(); + + $this->toast(trans('notifications.server_started', ['server' => $server->name])); + } catch (Exception $exception) { + $this->handleException($exception, $server->name, $server->serverProvider); + } + } + + public function stopServer(int $id): void + { + $server = $this->selectedNetwork->servers()->findOrFail($id); + + $this->authorize('stop', $server); + + try { + $server->serverProvider->client()->stop($server->provider_server_id); + + $server->markAsOffline(); + + $this->toast(trans('notifications.server_stopped', ['server' => $server->name])); + } catch (Exception $exception) { + $this->handleException($exception, $server->name, $server->serverProvider); + } + } + + public function rebootServer(int $id): void + { + $server = $this->selectedNetwork->servers()->findOrFail($id); + + $this->authorize('restart', $server); + + try { + $server->serverProvider->client()->reboot($server->provider_server_id); + + WaitForServerToStart::dispatch($server)->delay( + now()->addSeconds(30) + ); + + $server->markAsOffline(); + + $this->toast(trans('notifications.server_rebooted', ['server' => $server->name])); + } catch (Exception $exception) { + $this->handleException($exception, $server->name, $server->serverProvider); + } + } + + public function updatedServerType(): void + { + $this->filteredNetworkServers = $this->selectedNetworkServers->where('preset', $this->serverType); + } + + private function setNetwork(?Network $network): void + { + if ($network !== null) { + $this->selectedNetwork = $network; + $this->selectedNetworkServers = $network->servers()->latest()->get(); + $this->serverType = 'all'; + $this->filteredNetworkServers = $this->selectedNetworkServers; + } + } + + private function handleException(Exception $exception, string $name, ServerProvider $provider): void + { + if ($exception instanceof ServerNotFound) { + alert('notifications.server_not_found', FlashType::ERROR, ['server' => $name]); + } elseif ($exception instanceof ServerProviderError && $exception->getMessage() !== '') { + alert($exception->getMessage(), FlashType::ERROR); + } elseif ($exception instanceof ServerProviderAuthenticationException) { + alert(trans('notifications.server_provider_authentication_error', [ + 'provider' => ServerProviderTypeEnum::label($provider->type), + 'name' => $provider->name, + ]), FlashType::ERROR); + } else { + report($exception); + + alert('notifications.something_went_wrong', FlashType::ERROR); + } + } +} diff --git a/app/App/Token/Components/CreateTokenModal.php b/app/App/Token/Components/CreateTokenModal.php new file mode 100644 index 0000000..5e24145 --- /dev/null +++ b/app/App/Token/Components/CreateTokenModal.php @@ -0,0 +1,70 @@ + 'handle', + ]; + + public function handle(): RedirectResponse|Redirector|null + { + abort_if($this->user === null, 403); + + $this->token = $this->user->ownedTokens()->currentStatus(TokenStatusEnum::PENDING)->first(); + + if ($this->token === null) { + return $this->continue(); + } + + return null; + } + + public function continue(): RedirectResponse|Redirector + { + return redirect()->route('tokens.create'); + } + + public function cancel(): void + { + $this->token = null; + + $this->closeModal(); + } + + public function deletePendingToken(): RedirectResponse|Redirector + { + /** @var Token $token */ + $token = $this->token; + + $token->forceDelete(); + + TokenDeleted::dispatch($token); + + return $this->continue(); + } +} diff --git a/app/App/Token/Components/DeleteToken.php b/app/App/Token/Components/DeleteToken.php new file mode 100644 index 0000000..ac423f0 --- /dev/null +++ b/app/App/Token/Components/DeleteToken.php @@ -0,0 +1,123 @@ + 'askForConfirmation', + 'setOption' => 'selectOption', + ]; + + public function mount(): void + { + $this->options = [ + 'blockchain' => trans('tokens.delete_token_modal.option_blockchain'), + 'servers' => trans('tokens.delete_token_modal.option_servers'), + ]; + + $this->selectedOptions = ['blockchain']; + } + + public function getSelectedOptionsProperty(): array + { + return $this->selectedOptions; + } + + public function selectOption(string $option): void + { + if (! in_array($option, $this->selectedOptions, true)) { + array_push($this->selectedOptions, $option); + } else { + $this->selectedOptions = array_diff($this->selectedOptions, [$option]); + } + } + + public function askForConfirmation(int $id): void + { + $this->openModal(); + + $this->tokenId = $id; + $this->token = Token::findOrFail($id); + } + + public function destroy(): void + { + $this->authorize('delete', $this->token); + + foreach ($this->selectedOptions as $action) { + if ($action === 'servers') { + $this->destroyWithServers(); + } + } + + $this->destroyToken(); + + $this->modalClosed(); + + $this->redirectRoute('tokens'); + } + + public function cancel(): void + { + $this->tokenId = null; + + $this->modalClosed(); + } + + public function shouldBeDisabled(string $key): bool + { + if ($key === 'blockchain') { + return false; + } + + if ($key === 'servers') { + return $this->token->servers->count() === 0; + } + + return false; + } + + public function hasConfirmedName(): bool + { + return $this->token_name === $this->token->name; + } + + private function destroyToken(): void + { + $this->token->delete(); + + TokenDeleted::dispatch($this->token, $shouldDeleteServers = false); + } + + private function destroyWithServers(): void + { + foreach ($this->token->servers as $server) { + $server->delete(); + } + } +} diff --git a/app/App/Token/Components/DeployBlockchain.php b/app/App/Token/Components/DeployBlockchain.php new file mode 100644 index 0000000..4b4481c --- /dev/null +++ b/app/App/Token/Components/DeployBlockchain.php @@ -0,0 +1,103 @@ + 'askForConfirmation', + 'setNetworkOption' => 'selectOption', + ]; + + public function mount(): void + { + $this->options = [ + NetworkTypeEnum::MAINNET => trans('tokens.deploy_blockchain_modal.option_mainnet'), + NetworkTypeEnum::DEVNET => trans('tokens.deploy_blockchain_modal.option_devnet'), + NetworkTypeEnum::TESTNET => trans('tokens.deploy_blockchain_modal.option_testnet'), + ]; + + $this->selectedOption = NetworkTypeEnum::MAINNET; + } + + public function selectOption(string $option): void + { + $this->selectedOption = $option; + } + + public function askForConfirmation(int $id): void + { + $this->openModal(); + + $this->tokenId = $id; + $this->token = Token::findOrFail($id); + } + + public function deploy(): void + { + $serverConfig = $this->token->getMetaAttribute(TokenAttributeEnum::SERVER_CONFIG); + $serverProvider = $this->token->serverProviders()->findOrFail($serverConfig['server_provider_id']); + $network = $this->token->networks()->where('name', $this->selectedOption)->firstOrFail(); + + /** @var ServerProviderImage $ServerProviderImage */ + $ServerProviderImage = $serverProvider->images()->where('uuid', $serverProvider->client()->getImageId())->first(); + + $server = $network->servers()->create([ + 'server_provider_id' => $serverConfig['server_provider_id'], + 'name' => Format::withToken($serverConfig['name']), + 'server_provider_region_id' => $serverConfig['server_provider_region_id'], + 'server_provider_plan_id' => $serverConfig['server_provider_plan_id'], + 'server_provider_image_id' => $ServerProviderImage->id, + 'preset' => PresetTypeEnum::GENESIS, + ]); + + /** @var User $user */ + $user = $this->user; + + $server->setMetaAttribute(ServerAttributeEnum::DISCLAIMER_MODAL_SEEN, false); + $server->setMetaAttribute(ServerAttributeEnum::SERVER_CREATED_MODAL_SEEN, false); + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $user->id); + + ServerCreated::dispatch($server); + + $this->token->forgetServerConfiguration(); + + $this->redirectRoute('tokens.servers.show', [$this->token, $network, $server]); + } + + public function cancel(): void + { + $this->tokenId = null; + + $this->modalClosed(); + } +} diff --git a/app/App/Token/Components/LogoUpload.php b/app/App/Token/Components/LogoUpload.php new file mode 100644 index 0000000..31dc05f --- /dev/null +++ b/app/App/Token/Components/LogoUpload.php @@ -0,0 +1,93 @@ +token = $token; + $this->logo = $this->token->getFirstMedia('logo') !== null ? $this->token->getFirstMedia('logo')->getUrl() : null; + $this->imageDeleted = false; + } + + public function updatedImageSingle(): void + { + $this->authorize('update', $this->token); + + if (! $this->imageSingle instanceof TemporaryUploadedFile) { + $this->imageSingle = TemporaryUploadedFile::createFromLivewire($this->imageSingle); + } + + $this->validateImageSingle(); + + $this->setTokenImage(); + } + + public function setTokenImage(): void + { + /** @var TemporaryUploadedFile $imageSingle */ + $imageSingle = $this->imageSingle; + + $this->token + ->addMedia($imageSingle->getRealPath()) + ->withResponsiveImages() + ->usingName($imageSingle->hashName()) + ->toMediaCollection('logo'); + + $this->token->refresh(); + $this->logo = $this->token->logo; + $this->imageDeleted = false; + } + + public function deleteImageSingle(): void + { + /** @var Media $media */ + $media = $this->token->getFirstMedia('logo'); + + $media->delete(); + $this->token->refresh(); + + if ($this->imageSingle instanceof TemporaryUploadedFile) { + $this->imageSingle->delete(); + } + + $this->imageSingle = null; + $this->logo = null; + $this->imageDeleted = true; + } +} diff --git a/app/App/Token/Components/ManageTokenSecureShellKeys.php b/app/App/Token/Components/ManageTokenSecureShellKeys.php new file mode 100644 index 0000000..422b790 --- /dev/null +++ b/app/App/Token/Components/ManageTokenSecureShellKeys.php @@ -0,0 +1,144 @@ + 'selectOption', + 'handleSelect' => 'handleSelect', + 'refreshSecureShellKeys' => '$refresh', + ]; + + public function mount(Token $token): void + { + $this->token = $token; + $this->selectedOptions = array_merge($this->selectedOptions, $this->getTokenKeys()); + } + + public function getKeysProperty(): Collection + { + return $this->token->availableKeys(); + } + + public function getCanSubmitProperty(): bool + { + return (count(array_diff($this->selectedOptions, $this->getTokenKeys())) > 0 + || count(array_diff($this->getTokenKeys(), $this->selectedOptions)) > 0) + && count($this->selectedOptions) > 0; + } + + public function getTokenKeys(): array + { + return $this->token->secureShellKeys->pluck('id')->toArray(); + } + + public function isRegistered(int $option): bool + { + return in_array($option, $this->selectedOptions, true); + } + + public function selectOption(int $option): void + { + $this->authorize('manageKeys', $this->token); + + if (! in_array($option, array_values($this->selectedOptions), true)) { + $this->selectedOptions[] = $option; + } else { + $this->selectedOptions = array_diff($this->selectedOptions, [$option]); + } + } + + public function selectAll(): void + { + $this->authorize('manageKeys', $this->token); + + $this->selectedOptions = Arr::flatten($this->getKeysProperty()->pluck('id')); + } + + public function deselectAll(): void + { + $this->authorize('manageKeys', $this->token); + + $this->selectedOptions = []; + } + + public function store(): void + { + $this->authorize('manageKeys', $this->token); + + $this->token->secureShellKeys()->sync($this->selectedOptions); + + $this->toast(trans('tokens.secure-shell-keys.store_success'), 'success'); + + redirect()->to(route('tokens.show', $this->token)); + } + + public function storeKey(): void + { + $data = $this->validate([ + 'name' => [ + 'required', + 'max:255', + Rule::unique('secure_shell_keys', 'name')->where('user_id', Auth::id()), + ], + 'public_key' => [ + 'required', + new SecureShellKey(), + Rule::unique('secure_shell_keys', 'public_key')->where('user_id', Auth::id()), + ], + ]); + + $this->user->secureShellKeys()->create($data); + + $this->toast(trans('pages.user-settings.create_ssh_success'), 'success'); + + $this->name = null; + $this->public_key = null; + + if ($this->modalShown) { + $this->closeModal(); + } + + $this->emit('refreshSecureShellKeys'); + } + + public function toggleModal(): void + { + if ($this->modalShown) { + $this->closeModal(); + } else { + $this->openModal(); + } + } +} diff --git a/app/App/Token/Components/ManageTokens.php b/app/App/Token/Components/ManageTokens.php new file mode 100644 index 0000000..cf3c366 --- /dev/null +++ b/app/App/Token/Components/ManageTokens.php @@ -0,0 +1,79 @@ + 'selectToken', + 'setIndex' => 'setIndex', + ]; + + /** @var mixed */ + protected $queryString = [ + 'index' => ['except' => ''], + 'network' => ['except' => ''], + 'token' => ['except' => ''], + ]; + + public function mount(): void + { + $this->tokens = $this->user->tokens()->orderBy('name')->get(); + + if ($this->tokens->count() > 0) { + $this->selectedToken = $this->tokens->where('name', $this->token)->first() ?? $this->tokens->first(); + } else { + $this->selectedToken = null; + } + } + + public function render(): View + { + return view('livewire.manage-tokens', [ + 'tokens' => $this->tokens, + 'selectedToken' => $this->selectedToken, + ]); + } + + public function selectToken(int $id): void + { + $token = $this->user->tokens()->findOrFail($id); + + $this->token = $token->name; + + $this->selectedToken = $token; + } + + public function setIndex(int $id): void + { + $this->index = $id; + } + + public function editToken(int $id): void + { + $this->redirectRoute('tokens.show', $this->tokens->firstWhere('id', $id)); + } +} diff --git a/app/App/Token/Components/UpdateToken.php b/app/App/Token/Components/UpdateToken.php new file mode 100644 index 0000000..526415f --- /dev/null +++ b/app/App/Token/Components/UpdateToken.php @@ -0,0 +1,46 @@ + 'setDefaults', + 'setFeeDefaults' => 'setFeeDefaults', + ]; + + private function step1Rules(): array + { + /** @var User $user */ + $user = auth()->user(); + + return [ + 'chainName' => [ + 'required', 'max:32', 'alpha_dash', + Rule::unique('tokens', 'name') + ->where('user_id', $user->id) + ->whereNull('deleted_at') + ->ignore($this->tokenObject->id, 'id'), + ], + 'token' => ['required', 'max:6', 'alpha_num', new ReservedTokenName()], + 'symbol' => ['required', 'max:3'], + 'mainnetPrefix' => ['required', 'max:1', new AddressPrefix()], + 'devnetPrefix' => ['required', 'max:1', new AddressPrefix()], + 'testnetPrefix' => ['required', 'max:1', new AddressPrefix()], + ]; + } +} diff --git a/app/App/Token/Controllers/DeploymentConfigController.php b/app/App/Token/Controllers/DeploymentConfigController.php new file mode 100644 index 0000000..4c8a54a --- /dev/null +++ b/app/App/Token/Controllers/DeploymentConfigController.php @@ -0,0 +1,36 @@ +configurationPath(); + + if (! Storage::disk('token-config')->exists($path)) { + report(new RuntimeException('Trying to retrieve config.zip file for the token [ID: '.$network->token->id.'] but the file does not exist.')); + + return response('File not found!', 404); + } + + return Storage::disk('token-config')->download($path, 'config.zip'); + } + + public function store(Network $network, DeploymentConfigRequest $request): Response + { + $request->file->storeAs('', $network->configurationPath(), 'token-config'); + + return response()->noContent(); + } +} diff --git a/app/App/Token/Controllers/InstallationScriptController.php b/app/App/Token/Controllers/InstallationScriptController.php new file mode 100644 index 0000000..2403b5e --- /dev/null +++ b/app/App/Token/Controllers/InstallationScriptController.php @@ -0,0 +1,22 @@ +token, $network->name); + + return response()->streamDownload(function () use ($script) { + echo $script->script(); + }, 'install.sh'); + } +} diff --git a/app/App/Token/Controllers/TokenActivityController.php b/app/App/Token/Controllers/TokenActivityController.php new file mode 100644 index 0000000..a00e5d0 --- /dev/null +++ b/app/App/Token/Controllers/TokenActivityController.php @@ -0,0 +1,41 @@ +authorize('view', $token); + + $activity = Activity::causedBy($token)->latest()->paginate(); + + // Since user_id is stored in the `properties` column of the activity, we'll + // pre-load them here to prevent n+1 issues when displaying user's name in the UI. + /** @var \Illuminate\Support\Collection */ + $users = User::find( + $activity->getCollection() + ->map + ->userId() + ->filter() + ->unique() + ->values() + ); + + return view('app.tokens.activity', [ + 'token' => $token, + 'activities' => $activity->through(fn (Activity $activity) => [ + 'activity' => $activity, + 'user' => $users->firstWhere('id', $activity->userId()), + ]), + ]); + } +} diff --git a/app/App/Token/Controllers/TokenCollaboratorController.php b/app/App/Token/Controllers/TokenCollaboratorController.php new file mode 100644 index 0000000..cb23b81 --- /dev/null +++ b/app/App/Token/Controllers/TokenCollaboratorController.php @@ -0,0 +1,26 @@ +authorize('view', $token); + $this->authorizeAny(['createCollaborator', 'deleteCollaborator'], $token); + + if ($token->canBeEdited() && ! $token->onboarding()->available(TokenOnboardingStatusEnum::COLLABORATORS)) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.collaborators', ['token' => $token]); + } +} diff --git a/app/App/Token/Controllers/TokenController.php b/app/App/Token/Controllers/TokenController.php new file mode 100644 index 0000000..da33bc1 --- /dev/null +++ b/app/App/Token/Controllers/TokenController.php @@ -0,0 +1,36 @@ +authorize('view', $token); + + if (! $token->canBeEdited()) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.edit', ['token' => $token]); + } + + public function show(Token $token): RedirectResponse + { + $this->authorize('view', $token); + + return redirect()->route('tokens.details', [$token]); + } +} diff --git a/app/App/Token/Controllers/TokenDetailsController.php b/app/App/Token/Controllers/TokenDetailsController.php new file mode 100644 index 0000000..aa70556 --- /dev/null +++ b/app/App/Token/Controllers/TokenDetailsController.php @@ -0,0 +1,24 @@ +authorize('view', $token); + + $configuration = $token->config; + + return view('app.tokens.details', [ + 'token' => $token, + 'configuration' => $configuration, + ]); + } +} diff --git a/app/App/Token/Controllers/TokenInvitationController.php b/app/App/Token/Controllers/TokenInvitationController.php new file mode 100644 index 0000000..a224f9f --- /dev/null +++ b/app/App/Token/Controllers/TokenInvitationController.php @@ -0,0 +1,72 @@ +back()->with('status', self::ALERT_STATUS); + } + + $token = $invitation->token; + + /** @var User $user */ + $user = $request->user(); + + $token->shareWith($user, $invitation->role, $invitation->permissions); + + $invitation->delete(); + + alert('invitations.messages.accepted', FlashType::SUCCESS); + + $token->collaborators->each->notify(new CollaboratorAcceptedInvite($token, $user)); + + return redirect()->route('user.teams')->with('status', self::ALERT_STATUS); + } + + public static function canBeHandled(Request $request, ?Invitation $invitation): bool + { + if (is_null($invitation)) { + alert('invitations.messages.invitation_removed', FlashType::ERROR); + + return false; + } + + if ($invitation->isExpired()) { + alert('invitations.messages.invitation_expired', FlashType::ERROR); + + return false; + } + + if (is_null($invitation->user_id)) { + /** @var User $user */ + $user = $request->user(); + abort_unless($user->email === $invitation->email, 404); + } else { + abort_unless(Auth::id() === $invitation->user_id, 404); + } + + return true; + } +} diff --git a/app/App/Token/Controllers/TokenOnboardingController.php b/app/App/Token/Controllers/TokenOnboardingController.php new file mode 100644 index 0000000..3dc87e3 --- /dev/null +++ b/app/App/Token/Controllers/TokenOnboardingController.php @@ -0,0 +1,65 @@ +authorize('view', $token); + + if (! $token->canBeEdited()) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.onboard', ['token' => $token]); + } + + public function create(): View + { + // fetch existing draft token for user or create new, then redirect to onboarding + $token = Token::where('user_id', Auth::id())->currentStatus(TokenStatusEnum::PENDING)->first(); + + if ($token === null) { + // Create draft token that we use + $coin = Coin::where([ + 'name' => 'ARK', + 'symbol' => 'ARK', + ])->firstOrFail(); + + $token = Token::create([ + 'user_id' => Auth::id(), + 'coin_id' => $coin->id, + 'name' => Haiku::withToken(), + 'config' => null, + ]); + + $token->save(); + + TokenCreated::dispatch($token); + } + + return view('app.tokens.onboard', ['token' => $token]); + } + + public function update(Token $token): RedirectResponse + { + abort_unless($token->onboarding()->fulfilled(), 403); + + $token->update(['onboarded_at' => now()]); + + return redirect()->route('tokens', $token); + } +} diff --git a/app/App/Token/Controllers/TokenSecureShellKeyController.php b/app/App/Token/Controllers/TokenSecureShellKeyController.php new file mode 100644 index 0000000..9296366 --- /dev/null +++ b/app/App/Token/Controllers/TokenSecureShellKeyController.php @@ -0,0 +1,27 @@ +authorize('view', $token); + + if ($token->canBeEdited() && ! $token->onboarding()->available(TokenOnboardingStatusEnum::SECURE_SHELL_KEYS)) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.secure-shell-keys', [ + 'token' => $token, + ]); + } +} diff --git a/app/App/Token/Controllers/TokenServerActionController.php b/app/App/Token/Controllers/TokenServerActionController.php new file mode 100644 index 0000000..7131908 --- /dev/null +++ b/app/App/Token/Controllers/TokenServerActionController.php @@ -0,0 +1,64 @@ +authorize('update', $server); + + try { + $server->serverProvider->client()->start($server->provider_server_id); + + alert('tokens.servers.actions.started_success', FlashType::SUCCESS, ['server' => $server->name]); + } catch (Throwable) { + alert('tokens.servers.actions.started_failed', FlashType::ERROR, ['server' => $server->name]); + } + + return back(); + } + + public function stop(Token $token, Network $network, int $serverId): RedirectResponse + { + $server = Server::findOrFail($serverId); + $this->authorize('update', $server); + + try { + $server->serverProvider->client()->stop($server->provider_server_id); + + alert('tokens.servers.actions.stopped_success', FlashType::SUCCESS, ['server' => $server->name]); + } catch (Throwable) { + alert('tokens.servers.actions.stopped_failed', FlashType::ERROR, ['server' => $server->name]); + } + + return back(); + } + + public function reboot(Token $token, Network $network, int $serverId): RedirectResponse + { + $server = Server::findOrFail($serverId); + $this->authorize('update', $server); + + try { + $server->serverProvider->client()->reboot($server->provider_server_id); + + alert('tokens.servers.actions.rebooted_success', FlashType::SUCCESS, ['server' => $server->name]); + } catch (Throwable) { + alert('tokens.servers.actions.rebooted_failed', FlashType::ERROR, ['server' => $server->name]); + } + + return back(); + } +} diff --git a/app/App/Token/Controllers/TokenServerConfigurationController.php b/app/App/Token/Controllers/TokenServerConfigurationController.php new file mode 100644 index 0000000..b92bb78 --- /dev/null +++ b/app/App/Token/Controllers/TokenServerConfigurationController.php @@ -0,0 +1,31 @@ +authorize('view', $token); + + if (! $token->canBeEdited()) { + return redirect()->route('tokens.servers.index', $token); + } + + if (! $token->onboarding()->available(TokenOnboardingStatusEnum::SERVER_CONFIGURATION)) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.server-configuration', [ + 'token' => $token, + ]); + } +} diff --git a/app/App/Token/Controllers/TokenServerController.php b/app/App/Token/Controllers/TokenServerController.php new file mode 100644 index 0000000..c3008ae --- /dev/null +++ b/app/App/Token/Controllers/TokenServerController.php @@ -0,0 +1,51 @@ +authorize('view', $token); + + return view('app.tokens.servers.index', [ + 'token' => $token, + ]); + } + + public function create(Token $token, Network $network): View + { + $this->authorize('create', [Server::class, $token]); + + return view('app.tokens.servers.create', [ + 'token' => $token, + 'network' => $network, + ]); + } + + public function show(Token $token, Network $network, int $serverId): View|RedirectResponse + { + // This method does not use model binding to bind Server model because in the Blade template we render a Livewire component... + // However, since we want to display Deployment Failed modal even if the Server model is deleted, we can't use model binding + // as that will (for some weird reason) automatically throw 404 modal when Livewire component is hydrated... + + $server = Server::findOrFail($serverId); + + $this->authorize('view', $server); + + return view('app.tokens.servers.show', [ + 'token' => $token, + 'network' => $network, + 'server' => $server, + ]); + } +} diff --git a/app/App/Token/Controllers/TokenServerProviderController.php b/app/App/Token/Controllers/TokenServerProviderController.php new file mode 100644 index 0000000..14d59b0 --- /dev/null +++ b/app/App/Token/Controllers/TokenServerProviderController.php @@ -0,0 +1,27 @@ +authorize('view', $token); + + if ($token->canBeEdited() && ! $token->onboarding()->available(TokenOnboardingStatusEnum::SERVER_PROVIDERS)) { + return redirect()->route('tokens.show', $token); + } + + return view('app.tokens.server-providers', [ + 'token' => $token, + ]); + } +} diff --git a/app/App/Token/Notifications/TokenDeleted.php b/app/App/Token/Notifications/TokenDeleted.php new file mode 100644 index 0000000..6a21ec3 --- /dev/null +++ b/app/App/Token/Notifications/TokenDeleted.php @@ -0,0 +1,34 @@ +fromToken($this->token, [ + 'content' => trans('notifications.subjects.token_deleted', ['token' => $this->token->name]), + ]) + ->success() + ->getContent(); + } +} diff --git a/app/App/Token/Requests/DeploymentConfigRequest.php b/app/App/Token/Requests/DeploymentConfigRequest.php new file mode 100644 index 0000000..fa9708f --- /dev/null +++ b/app/App/Token/Requests/DeploymentConfigRequest.php @@ -0,0 +1,22 @@ + ['file', 'required', 'mimetypes:application/zip', 'min:1', 'max:50'], + ]; + } +} diff --git a/app/App/User/Components/ManageSecureShellKeys.php b/app/App/User/Components/ManageSecureShellKeys.php new file mode 100644 index 0000000..f34cff0 --- /dev/null +++ b/app/App/User/Components/ManageSecureShellKeys.php @@ -0,0 +1,24 @@ + '$refresh']; + + public function getKeysProperty(): Collection + { + return $this->user->secureShellKeys; + } +} diff --git a/app/App/User/Components/UpdateUserAccount.php b/app/App/User/Components/UpdateUserAccount.php new file mode 100644 index 0000000..111b1ab --- /dev/null +++ b/app/App/User/Components/UpdateUserAccount.php @@ -0,0 +1,179 @@ +has(['email', 'signature'])) { + // @phpstan-ignore-next-line + if (! $request->hasValidSignature()) { + $this->invalidLink = true; + } elseif ($this->emailConfirmationLinkExpired($request)) { + $this->expiredLink = true; + } else { + $this->updateEmail($request->input('email')); + } + + // We want to remove the signature from the query string so it's not persisted if the user refreshes the page... + $this->signature = null; + } + + $this->name = $this->user->name; + $this->email = $this->user->email; + } + + public function update() : void + { + Validator::make([ + 'name' => $this->name, + 'email' => $this->email, + ], $this->validationRules())->validate(); + + $this->user->fill([ + 'name' => $this->name, + 'email' => $this->email, + ]); + + // If user wants to change email, we want to first have them confirm this change... + if ($this->user->isDirty('email')) { + $this->confirmEmailChangeModal = true; + + return; + } + + $this->user->save(); + + $this->toast(trans('pages.user-settings.profile.saved')); + } + + public function closeEmailConfirmationModal() : void + { + $this->confirmEmailChangeModal = false; + $this->confirmEmailChangeModalConfirmed = false; + $this->password = ''; + + $this->closeModal(); + } + + public function confirmEmailChange() : void + { + $this->validate([ + 'password' => ['required', 'string', new CurrentPassword($this->user)], + ]); + + $this->user->sendEmailChangeConfirmationMail($this->email); + + $this->confirmEmailChangeModalConfirmed = true; + } + + public function cancelConfirmationEmail() : void + { + $this->user->forgetMetaAttribute('email_to_update'); + $this->user->forgetMetaAttribute('email_to_update_stored_at'); + } + + public function resendConfirmationEmail() : void + { + $pendingEmail = $this->user->getMetaAttribute('email_to_update'); + + // User has confirmed & updated the email in the meanwhile, so just refresh to avoid weird state... + if ($pendingEmail === '' || $pendingEmail === null) { + $this->redirectRoute('user.profile'); + + return; + } + + $this->user->sendEmailChangeConfirmationMail($this->user->getMetaAttribute('email_to_update')); + + $this->toast(trans('pages.user-settings.email-change.resend')); + } + + public function closeEmailUpdatedFeedbackModal() : void + { + $this->emailUpdated = false; + $this->invalidLink = false; + $this->expiredLink = false; + + $this->closeModal(); + } + + public function render() : Renderable + { + return view('livewire.update-user-account'); + } + + private function validationRules() : array + { + return [ + 'email' => ['required', 'max:255', 'email', Rule::unique('users')->ignore($this->user)], + 'name' => 'required|string|max:50', + ]; + } + + private function updateEmail(string $email) : void + { + $this->user->update([ + 'email' => strtolower($email), + ]); + + $this->user->forgetMetaAttribute('email_to_update'); + $this->user->forgetMetaAttribute('email_to_update_stored_at'); + + $this->emailUpdated = true; + } + + private function emailConfirmationLinkExpired(Request $request) : bool + { + $pendingEmail = $this->user->getMetaAttribute('email_to_update'); + + if ($pendingEmail === null) { + return true; + } + + return strtolower($request->input('email')) !== strtolower($pendingEmail) + ? true + : Carbon::now()->gte(Carbon::createFromTimestamp($request->input('expires'))); + } +} diff --git a/app/App/User/Mail/ConfirmEmailChange.php b/app/App/User/Mail/ConfirmEmailChange.php new file mode 100644 index 0000000..cad3ddd --- /dev/null +++ b/app/App/User/Mail/ConfirmEmailChange.php @@ -0,0 +1,41 @@ +subject($subject = trans('mails.subjects.email-confirm-change'))->view('mails.confirm-email-change', [ + 'subject' => $subject, + 'name' => $this->name, + 'url' => $this->confirmationUrl(), + ]); + } + + private function confirmationUrl() : string + { + $ttl = now()->addHours(24); + + return URL::temporarySignedRoute('user.profile', $ttl, [ + 'email' => $this->email, + ]); + } +} diff --git a/app/App/User/Mail/PersonalDataExport.php b/app/App/User/Mail/PersonalDataExport.php new file mode 100644 index 0000000..7d1bead --- /dev/null +++ b/app/App/User/Mail/PersonalDataExport.php @@ -0,0 +1,35 @@ +zipFilename); + + // @codeCoverageIgnoreStart + if (static::$toMailCallback !== null) { + return call_user_func(static::$toMailCallback, $notifiable, $downloadUrl); + } + // @codeCoverageIgnoreEnd + + return (new MailMessage()) + ->subject(trans('mails.subjects.download_personal_data')) + ->view('mails.personal-data-export', [ + 'subject' => trans('mails.subjects.download_personal_data'), + 'url' => $downloadUrl, + 'date' => $this->deletionDatetime->format('Y-m-d H:i:s'), + ]); + } +} diff --git a/app/App/View/Components/BlockchainLogo.php b/app/App/View/Components/BlockchainLogo.php new file mode 100644 index 0000000..7d25b38 --- /dev/null +++ b/app/App/View/Components/BlockchainLogo.php @@ -0,0 +1,39 @@ +size) { + 'small' => 'w-11 h-11', + default => 'w-20 h-20', + }; + } + + public function rounded(): string + { + return match ($this->size) { + 'small' => 'rounded', + default => 'rounded-xl', + }; + } +} diff --git a/app/App/View/Components/SortByButton.php b/app/App/View/Components/SortByButton.php new file mode 100644 index 0000000..e5d4173 --- /dev/null +++ b/app/App/View/Components/SortByButton.php @@ -0,0 +1,25 @@ +hasMany(Token::class); + } + + public function getSlugOptions(): SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('name') + ->saveSlugsTo('slug') + ->slugsShouldBeNoLongerThan(95); // 100 but room for suffix + } +} diff --git a/app/Domain/Collaborator/Actions/InviteCollaboratorAction.php b/app/Domain/Collaborator/Actions/InviteCollaboratorAction.php new file mode 100644 index 0000000..65574ea --- /dev/null +++ b/app/Domain/Collaborator/Actions/InviteCollaboratorAction.php @@ -0,0 +1,58 @@ +emailAlreadyOnToken($token, $email)) { + throw ValidationException::withMessages([ + 'email' => trans('tokens.user_already_on_token', ['email' => $email]), + ]); + } + + if ($this->emailAlreadyInvited($token, $email)) { + throw ValidationException::withMessages([ + 'email' => trans('tokens.user_already_invited_to_token', ['email' => $email]), + ]); + } + + $invitedUser = User::where('email', $email)->first(); + + $invitation = $token->invitations()->create([ + 'uuid' => Uuid::uuid4(), + 'user_id' => $invitedUser?->id, + 'role' => 'collaborator', + 'permissions' => $permissions, + 'email' => $email, + ]); + + if (is_null($invitation->user_id)) { + Mail::to($invitation->email)->send(new InviteNewUser($invitation)); + } else { + /** @var User $invitedUser */ + $invitedUser->notify(new InviteExistingUser($invitation)); + } + } + + private function emailAlreadyOnToken(Token $token, string $email): bool + { + return $token->collaborators()->where('email', $email)->exists(); + } + + private function emailAlreadyInvited(Token $token, string $email): bool + { + return $token->invitations()->where('email', $email)->exists(); + } +} diff --git a/app/Domain/Collaborator/Models/Collaborator.php b/app/Domain/Collaborator/Models/Collaborator.php new file mode 100644 index 0000000..1cd4798 --- /dev/null +++ b/app/Domain/Collaborator/Models/Collaborator.php @@ -0,0 +1,37 @@ + 'json']; + + public static function availablePermissions(): array + { + return [ + 'token:delete', + 'token:update', + 'collaborator:create', + 'collaborator:delete', + 'server-provider:create', + 'server-provider:delete', + 'server-provider:update', + 'server:create', + 'server:delete', + 'server:rename', + 'server:restart', + 'server:start', + 'server:stop', + 'ssh-key:manage', + ]; + } +} diff --git a/app/Domain/Collaborator/Models/Invitation.php b/app/Domain/Collaborator/Models/Invitation.php new file mode 100644 index 0000000..59fd793 --- /dev/null +++ b/app/Domain/Collaborator/Models/Invitation.php @@ -0,0 +1,45 @@ + 'json']; + + public function token(): BelongsTo + { + return $this->belongsTo(Token::class); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function isExpired(): bool + { + return Carbon::now()->subWeek()->gte($this->created_at); + } + + public static function findByUuid(string $token): self + { + return static::where('uuid', $token)->firstOrFail(); + } +} diff --git a/app/Domain/SecureShell/Contracts/Script.php b/app/Domain/SecureShell/Contracts/Script.php new file mode 100644 index 0000000..98a55e1 --- /dev/null +++ b/app/Domain/SecureShell/Contracts/Script.php @@ -0,0 +1,36 @@ +belongsToMany(Token::class); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function fingerprint() : string + { + // Segments of a public key: algorithm / public key contents / identifier (email) + $segments = explode(' ', $this->public_key, 3); + $contents = (string) base64_decode($segments[1], true); + + return implode(':', str_split(md5($contents), 2)); + } + + protected static function booted() : void + { + static::saving(function (self $model) : void { + $model->fill([ + 'fingerprint' => $model->fingerprint(), + ]); + }); + } +} diff --git a/app/Domain/SecureShell/Policies/SecureShellKeyPolicy.php b/app/Domain/SecureShell/Policies/SecureShellKeyPolicy.php new file mode 100644 index 0000000..8385159 --- /dev/null +++ b/app/Domain/SecureShell/Policies/SecureShellKeyPolicy.php @@ -0,0 +1,19 @@ +user->id === $user->id; + } +} diff --git a/app/Domain/SecureShell/Rules/SecureShellKey.php b/app/Domain/SecureShell/Rules/SecureShellKey.php new file mode 100644 index 0000000..fa9bc6e --- /dev/null +++ b/app/Domain/SecureShell/Rules/SecureShellKey.php @@ -0,0 +1,43 @@ +coin->name).'.'.strtolower($token->name); + + if (view()->exists($scriptPrefix.$scriptTokenPath.'.'.$scriptType)) { + return $scriptPrefix.$scriptTokenPath.'.'.$scriptType; + } + + return $scriptPrefix.strtolower($token->coin->name).'.'.strtolower($token->coin->symbol).'.'.$scriptType; + } +} diff --git a/app/Domain/SecureShell/Scripts/Concerns/ManagesScriptVariables.php b/app/Domain/SecureShell/Scripts/Concerns/ManagesScriptVariables.php new file mode 100644 index 0000000..c2123a8 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/Concerns/ManagesScriptVariables.php @@ -0,0 +1,47 @@ +server->token; + $network = $this->server->network; + + $result = array_merge((array) $token->config, $attributes, [ + // All + 'username' => $this->user(), + 'user_password' => $this->server->user_password, + 'sudo_password' => $this->server->sudo_password, + 'privateKey' => $token->getPrivateKey(), + 'publicKey' => $token->keypair['publicKey'] ?? '', + 'authorizedKeys' => $this->server->getAuthorizedKeys(), + 'token' => $this->user(), + 'name' => $token->name, + 'network' => $network->name, + 'epoch' => $network->epoch(), + 'ipAddress' => $this->server->ip_address, + 'addressPrefix' => $network->base58Prefix(), + 'server' => $this->server, + 'explorerPath' => '$HOME/core-explorer', + // These are temporary URLs available during installation. They are no longer accessible after 30 minutes. + 'coreVersion' => URL::temporarySignedRoute('server.deployment.status', now()->addMinutes(30), ['server' => $this->server->id]), + 'deploymentStatus' => URL::temporarySignedRoute('server.deployment.status', now()->addMinutes(30), ['server' => $this->server->id]), + 'storeConfigUrl' => URL::temporarySignedRoute('server.deployment.config.store', now()->addMinutes(30), ['network' => $network->id]), + 'getConfigUrl' => URL::temporarySignedRoute('server.deployment.config.show', now()->addMinutes(30), ['network' => $network->id]), + 'installationScriptUrl' => URL::temporarySignedRoute('server.deployment.installation-script.show', now()->addMinutes(30), ['network' => $network->id]), + ]); + + if (array_key_exists('databaseName', $result)) { + $result['databaseName'] = Str::snake(strtolower($result['databaseName'])); + } + + return $result; + } +} diff --git a/app/Domain/SecureShell/Scripts/ManualScript.php b/app/Domain/SecureShell/Scripts/ManualScript.php new file mode 100644 index 0000000..c08a647 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ManualScript.php @@ -0,0 +1,56 @@ +token->network($this->network); + + return View::make( + $this->getScriptPath($this->token, 'provision-manual'), + array_merge((array) $this->token->config, [ + 'token' => $this->user(), + 'name' => $this->token->name, + 'peers' => $network->getGenesis()->ip_address, + 'network' => $network->name, + 'epoch' => $network->epoch(), + 'addressPrefix' => $network->base58Prefix(), + 'explorerPath' => '\\'.'$HOME/core-explorer', + ]) + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionExplorer.php b/app/Domain/SecureShell/Scripts/ProvisionExplorer.php new file mode 100644 index 0000000..bd1cac8 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionExplorer.php @@ -0,0 +1,49 @@ +token = $server->token; + } + + public function name(): string + { + return trans('scripts.names.provision_explorer', ['server' => $this->server->name]); + } + + public function script(): string + { + return View::make( + $this->getScriptPath($this->token, 'provision-explorer'), + $this->makeScriptVariables() + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token ?? ''; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionForger.php b/app/Domain/SecureShell/Scripts/ProvisionForger.php new file mode 100644 index 0000000..9686684 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionForger.php @@ -0,0 +1,53 @@ +token = $server->token; + } + + public function name(): string + { + return trans('scripts.names.provision_forger', ['server' => $this->server->name]); + } + + public function script(): string + { + return View::make( + $this->getScriptPath($this->token, 'provision-forger'), + $this->makeScriptVariables([ + 'passphrase' => $this->server->delegate_passphrase, + 'passphrasePassword' => $this->server->delegate_password, // only relevant for bip38 + 'passphraseMethod' => is_null($this->server->delegate_password) ? 'bip39' : 'bip38', + ]) + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionGenesis.php b/app/Domain/SecureShell/Scripts/ProvisionGenesis.php new file mode 100644 index 0000000..7105810 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionGenesis.php @@ -0,0 +1,52 @@ +token = $server->token; + } + + public function name(): string + { + return trans('scripts.names.provision_genesis', ['server' => $this->server->name]); + } + + public function script(): string + { + return View::make( + $this->getScriptPath($this->token, 'provision-genesis'), + $this->makeScriptVariables([ + 'explorerPath' => '\\'.'$HOME/core-explorer', + 'tokenPath' => '\\'.'$HOME/core-token', + ]) + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionRelay.php b/app/Domain/SecureShell/Scripts/ProvisionRelay.php new file mode 100644 index 0000000..145a8fd --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionRelay.php @@ -0,0 +1,49 @@ +token = $server->token; + } + + public function name(): string + { + return trans('scripts.names.provision_relay', ['server' => $this->server->name]); + } + + public function script(): string + { + return View::make( + $this->getScriptPath($this->token, 'provision-relay'), + $this->makeScriptVariables() + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionSeed.php b/app/Domain/SecureShell/Scripts/ProvisionSeed.php new file mode 100644 index 0000000..25dfe7d --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionSeed.php @@ -0,0 +1,49 @@ +token = $server->token; + } + + public function name(): string + { + return trans('scripts.names.provision_seed', ['server' => $this->server->name]); + } + + public function script(): string + { + return View::make( + $this->getScriptPath($this->token, 'provision-seed'), + $this->makeScriptVariables() + )->render(); + } + + public function user(): string + { + return $this->token->normalized_token; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Scripts/ProvisionUser.php b/app/Domain/SecureShell/Scripts/ProvisionUser.php new file mode 100644 index 0000000..535d717 --- /dev/null +++ b/app/Domain/SecureShell/Scripts/ProvisionUser.php @@ -0,0 +1,53 @@ + $this->server->name]); + } + + public function script(): string + { + $token = $this->server->token; + + return View::make($this->getScriptPath($token, 'provision-user'), [ + 'username' => $token->normalized_token, + 'preset' => $this->server->preset, + 'user_password' => $this->server->user_password, + 'sudo_password' => $this->server->sudo_password, + 'privateKey' => $token->getPrivateKey(), + 'publicKey' => $token->keypair['publicKey'] ?? '', + 'authorizedKeys' => $this->server->getAuthorizedKeys(), + // These are temporary URLs available during installation. They are no longer accessible after 30 minutes. + 'deploymentStatus' => URL::temporarySignedRoute('server.deployment.status', now()->addMinutes(30), ['server' => $this->server->id]), + ])->render(); + } + + public function user(): string + { + return 'root'; + } + + public function timeout(): int + { + return ServerTask::DEFAULT_TIMEOUT; + } +} diff --git a/app/Domain/SecureShell/Services/SecureShell.php b/app/Domain/SecureShell/Services/SecureShell.php new file mode 100644 index 0000000..db77a4a --- /dev/null +++ b/app/Domain/SecureShell/Services/SecureShell.php @@ -0,0 +1,144 @@ +ensureWorkingDirectoryExists(); + + $this->upload(); + } catch (ProcessTimedOutException) { + return $this->task->markAsTimedOut(); + } + + $output = $this->runInline(sprintf( + 'bash %s 2>&1 | tee %s', + $this->scriptFile(), + $this->outputFile() + ), $this->task->options['timeout'] ?? 60); + + return $this->updateForResponse($output); + } + + public function runWithUser(): ServerTask + { + try { + $this->upload(); + } catch (ProcessTimedOutException) { + return $this->task->markAsTimedOut(); + } + + $output = $this->runInline(sprintf( + 'su - %s -c "bash %s 2>&1" | tee %s', + $this->task->user, + $this->scriptFile(), + $this->outputFile() + ), $this->task->options['timeout'] ?? 60); + + return $this->updateForResponse($output); + } + + private function updateForResponse(ShellResponse $response): ServerTask + { + $this->task->setStatus($response->timedOut ? 'timeout' : 'finished'); + + return tap($this->task)->update([ + 'exit_code' => $response->exitCode, + 'output' => $response->output, + ]); + } + + private function ensureWorkingDirectoryExists(): void + { + $this->runInline('mkdir -p '.$this->path(), 10); + } + + private function upload(): void + { + $process = Process::fromShellCommandline(SecureShellCommand::forUpload( + $this->task->ipAddress(), + $this->task->port(), + $this->task->ownerKeyPath(), + $this->rootUser, + $localScript = $this->writeScript(), + $this->scriptFile() + ), base_path())->setTimeout(15); + + $response = ShellProcessRunner::run($process); + + unlink($localScript); + } + + private function writeScript(): string + { + $hash = md5(Str::random(20).$this->task->script); + + if (! is_dir(storage_path('app/scripts'))) { + mkdir(storage_path('app/scripts'), 0755, true); + } + + return tap(storage_path('app/scripts').'/'.$hash, fn ($path) => file_put_contents($path, $this->task->script)); + } + + private function runInline(string $script, int $timeout = 60): ShellResponse + { + $token = Str::random(20); + + return ShellProcessRunner::run($this->toProcess('\'bash -s \' << \''.$token.'\' +'.$script.' +'.$token, $timeout)); + } + + private function path(): string + { + return "/home/{$this->rootUser}/.deployer"; + } + + private function scriptFile(): string + { + return $this->getPath().'.sh'; + } + + private function outputFile(): string + { + return $this->getPath().'.out'; + } + + private function toProcess(string $script, int $timeout): Process + { + return Process::fromShellCommandline( + SecureShellCommand::forScript( + $this->task->ipAddress(), + $this->task->port(), + $this->task->ownerKeyPath(), + $this->rootUser, + $script + ) + )->setTimeout($timeout); + } + + private function getPath(): string + { + return $this->path().'/'.Str::snake(class_basename($this->task->type)); + } +} diff --git a/app/Domain/SecureShell/Services/SecureShellCommand.php b/app/Domain/SecureShell/Services/SecureShellCommand.php new file mode 100644 index 0000000..6b45499 --- /dev/null +++ b/app/Domain/SecureShell/Services/SecureShellCommand.php @@ -0,0 +1,31 @@ +run(); + + [$publicKey, $privateKey] = [ + file_get_contents(storage_path('app/'.$name.'.pub')), + file_get_contents(storage_path('app/'.$name)), + ]; + + File::delete(storage_path('app/'.$name.'.pub')); + File::delete(storage_path('app/'.$name)); + + return [ + 'publicKey' => $publicKey, + 'privateKey' => $privateKey, + ]; + } + + public function storeFor(Token $token): string + { + return tap(storage_path('app/keys/'.$token->id), function ($path) use ($token): void { + $this->ensureKeyDirectoryExists(); + + $this->ensureFileExists($path, $token->getPrivateKey(), 0600); + }); + } + + private function ensureKeyDirectoryExists(): void + { + if (! is_dir(storage_path('app/keys'))) { + mkdir(storage_path('app/keys'), 0755, true); + } + } + + private function ensureFileExists(string $path, string $contents, int $chmod): void + { + file_put_contents($path, $contents); + + chmod($path, $chmod); + } +} diff --git a/app/Domain/SecureShell/Services/ShellProcessRunner.php b/app/Domain/SecureShell/Services/ShellProcessRunner.php new file mode 100644 index 0000000..77ce3dc --- /dev/null +++ b/app/Domain/SecureShell/Services/ShellProcessRunner.php @@ -0,0 +1,23 @@ +run(); + } catch (ProcessTimedOutException) { + $timedOut = true; + } + + return new ShellResponse($process->getExitCode(), $process->getOutput(), $timedOut ?? false); + } +} diff --git a/app/Domain/SecureShell/Services/ShellResponse.php b/app/Domain/SecureShell/Services/ShellResponse.php new file mode 100644 index 0000000..75e4880 --- /dev/null +++ b/app/Domain/SecureShell/Services/ShellResponse.php @@ -0,0 +1,12 @@ + + */ + public function cast(mixed $value): Collection + { + return new Collection(array_map( + fn (mixed $data) => is_a($data, Image::class) ? $data : new Image(...$data), + $value + )); + } +} diff --git a/app/Domain/Server/DTO/Casters/PlanCollectionCaster.php b/app/Domain/Server/DTO/Casters/PlanCollectionCaster.php new file mode 100644 index 0000000..1d6cc01 --- /dev/null +++ b/app/Domain/Server/DTO/Casters/PlanCollectionCaster.php @@ -0,0 +1,26 @@ + + */ + public function cast(mixed $value): Collection + { + return new Collection(array_map( + fn (mixed $data) => is_a($data, Plan::class) ? $data : new Plan(...$data), + $value + )); + } +} diff --git a/app/Domain/Server/DTO/Casters/RegionCollectionCaster.php b/app/Domain/Server/DTO/Casters/RegionCollectionCaster.php new file mode 100644 index 0000000..8578490 --- /dev/null +++ b/app/Domain/Server/DTO/Casters/RegionCollectionCaster.php @@ -0,0 +1,26 @@ + + */ + public function cast(mixed $value): Collection + { + return new Collection(array_map( + fn (mixed $data) => is_a($data, Region::class) ? $data : new Region(...$data), + $value + )); + } +} diff --git a/app/Domain/Server/DTO/Image.php b/app/Domain/Server/DTO/Image.php new file mode 100644 index 0000000..cc66071 --- /dev/null +++ b/app/Domain/Server/DTO/Image.php @@ -0,0 +1,16 @@ + */ + #[CastWith(ImageCollectionCaster::class)] + public Collection $items; +} diff --git a/app/Domain/Server/DTO/Plan.php b/app/Domain/Server/DTO/Plan.php new file mode 100644 index 0000000..1ec4ce9 --- /dev/null +++ b/app/Domain/Server/DTO/Plan.php @@ -0,0 +1,28 @@ + */ + #[CastWith(PlanCollectionCaster::class)] + public Collection $items; +} diff --git a/app/Domain/Server/DTO/Region.php b/app/Domain/Server/DTO/Region.php new file mode 100644 index 0000000..7bbe1ff --- /dev/null +++ b/app/Domain/Server/DTO/Region.php @@ -0,0 +1,16 @@ + */ + #[CastWith(RegionCollectionCaster::class)] + public Collection $items; +} diff --git a/app/Domain/Server/DTO/SecureShellKey.php b/app/Domain/Server/DTO/SecureShellKey.php new file mode 100644 index 0000000..8dc7a45 --- /dev/null +++ b/app/Domain/Server/DTO/SecureShellKey.php @@ -0,0 +1,16 @@ + array_merge( + $this->serverStates(), + $this->coreStates(['genesis' => true]), + $this->explorerStates(), + $this->finalizingStates(), + ), + ]; + } + + public function getSeedStates(): array + { + return [ + 'seed' => array_merge( + $this->serverStates(), + $this->coreStates(), + $this->finalizingStates(), + ), + ]; + } + + public function getRelayStates(): array + { + return [ + 'relay' => array_merge( + $this->serverStates(), + $this->coreStates(), + $this->finalizingStates(), + ), + ]; + } + + public function getForgerStates(): array + { + return [ + 'forger' => array_merge( + $this->serverStates(), + $this->coreStates(['forger' => true]), + $this->finalizingStates(), + ), + ]; + } + + public function getExplorerStates(): array + { + return [ + 'explorer' => array_merge( + $this->serverStates(), + $this->coreStates(), + $this->explorerStates(), + $this->finalizingStates(), + ), + ]; + } + + public function getGroupStates(): array + { + return array_merge( + $this->getGenesisStates(), + $this->getSeedStates(), + $this->getRelayStates(), + $this->getForgerStates(), + $this->getExplorerStates(), + ); + } + + private function serverStates(): array + { + return [ + 'server' => [ + self::PROVISIONING, + self::CONFIGURING_LOCALE, + self::INSTALLING_SYSTEM_DEPENDENCIES, + self::INSTALLING_NODEJS, + self::INSTALLING_YARN, + self::INSTALLING_PM2, + self::INSTALLING_PROGRAM_DEPENDENCIES, + self::INSTALLING_POSTGRESQL, + self::INSTALLING_NTP, + self::INSTALLING_JEMALLOC, + self::UPDATING_SYSTEM, + self::SECURING_NODE, + ], + ]; + } + + private function coreStates(array $options = []): array + { + $states = [ + self::INSTALLING_CORE, + self::CREATING_CORE_ALIAS, + self::GENERATING_NETWORK_CONFIGURATION, + self::STORE_CONFIG, + self::FETCH_CONFIG, + self::CONFIGURING_DATABASE, + self::CONFIGURING_FORGER, + ]; + + if (! array_key_exists('genesis', $options)) { + $states = array_diff($states, [self::GENERATING_NETWORK_CONFIGURATION, self::STORE_CONFIG]); + } else { + $states = array_diff($states, [self::FETCH_CONFIG]); + } + + if (! array_key_exists('forger', $options)) { + $states = array_diff($states, [self::CONFIGURING_FORGER]); + } + + return [ + 'core' => $states, + ]; + } + + private function explorerStates(): array + { + $states = [ + self::INSTALLING_DOCKER, + self::CLONING_EXPLORER, + self::CONFIGURING_EXPLORER, + self::BUILDING_EXPLORER, + ]; + + return [ + 'explorer' => $states, + ]; + } + + private function finalizingStates(): array + { + return [ + 'finalizing' => [ + self::STARTING_PROCESSES, + self::CREATING_BOOT_SCRIPT, + self::PROVISIONED, + ], + ]; + } +} diff --git a/app/Domain/Server/Enums/ServerTaskStatusEnum.php b/app/Domain/Server/Enums/ServerTaskStatusEnum.php new file mode 100644 index 0000000..6de134c --- /dev/null +++ b/app/Domain/Server/Enums/ServerTaskStatusEnum.php @@ -0,0 +1,33 @@ + 'datetime', + 'provisioned_at' => 'datetime', + 'extra_attributes' => 'array', + 'sudo_password' => 'encrypted', + 'user_password' => 'encrypted', + 'delegate_passphrase' => 'encrypted', + 'delegate_password' => 'encrypted', + ]; + + protected array $enums = [ + 'preset' => PresetTypeEnum::class.':nullable', + ]; + + /** + * The event map for the model. + * + * @var array + */ + protected $dispatchesEvents = [ + 'deleted' => ServerDeleted::class, + 'updating' => ServerUpdating::class, + ]; + + public function creator() : ?User + { + return User::where('id', $this->getMetaAttribute(ServerAttributeEnum::CREATOR))->first(); + } + + public function token(): BelongsToThrough + { + return $this->belongsToThrough(Token::class, Network::class); + } + + public function network(): BelongsTo + { + return $this->belongsTo(Network::class); + } + + public function serverProvider(): BelongsTo + { + return $this->belongsTo(ServerProvider::class); + } + + public function plan(): HasOne + { + return $this->hasOne(ServerProviderPlan::class, 'id', 'server_provider_plan_id'); + } + + public function region(): HasOne + { + return $this->hasOne(ServerProviderRegion::class, 'id', 'server_provider_region_id'); + } + + public function image(): HasOne + { + return $this->hasOne(ServerProviderImage::class, 'id', 'server_provider_image_id'); + } + + public function tasks(): HasMany + { + return $this->hasMany(ServerTask::class); + } + + public function isGenesis(): bool + { + if ($this->preset !== null) { + return PresetTypeEnum::isGenesis($this->preset); + } + + return false; + } + + public function isSeed(): bool + { + if ($this->preset !== null) { + return PresetTypeEnum::isSeed($this->preset); + } + + return false; + } + + public function isRelay(): bool + { + if ($this->preset !== null) { + return PresetTypeEnum::isRelay($this->preset); + } + + return false; + } + + public function isForger(): bool + { + if ($this->preset !== null) { + return PresetTypeEnum::isForger($this->preset); + } + + return false; + } + + public function isExplorer(): bool + { + if ($this->preset !== null) { + return PresetTypeEnum::isExplorer($this->preset); + } + + return false; + } + + public function hasAuthorizedKeys(): bool + { + return (count($this->getAuthorizedKeys()) - 1) > 0; + } + + public function getAuthorizedKeys(): array + { + // Include user keys and our app's key + return array_merge( + $this->token->secureShellKeys()->pluck('public_key')->toArray(), + [$this->token->keypair['publicKey'] ?? []] + ); + } + + public function addTask(Script $script): ServerTask + { + $type = get_class($script); + + $task = $this->tasks()->whereType($type)->first(); + + if ($task !== null) { + return $task; + } + + $options = ['timeout' => $script->timeout()]; + + $task = $this->tasks()->create([ + 'type' => $type, + 'name' => $script->name(), + 'user' => $script->user(), + 'options' => $options, + 'script' => $script->script(), + 'output' => '', + ]); + + $task->setStatus('pending'); + + return $task; + } + + public function isReadyForProvisioning(): bool + { + if ($this->isProvisioning()) { + return false; + } + + return (bool) $this->ip_address; + } + + public function isProvisioning(): bool + { + return in_array($this->status, static::PROVISIONING_STATES, true); + } + + public function isProvisioned(): bool + { + return $this->provisioned_at !== null; + } + + public function isFailed(): bool + { + return $this->status === 'failed'; + } + + public function markAsOnline() : self + { + $this->setStatus('online'); + + return $this; + } + + public function isOnline() : bool + { + return $this->status === 'online'; + } + + public function markAsOffline() : self + { + $this->setStatus('offline'); + + return $this; + } + + public function isOffline() : bool + { + return $this->status === 'offline'; + } + + public function olderThan(int $minutes): bool + { + return $this->created_at?->lte(Carbon::now()->subMinutes($minutes)) ?? false; + } + + // We use those methods to get faster and more consistent access to commonly used nested URLs. + public function pathShow(): string + { + return route('tokens.servers.show', [$this->token, $this->network, $this]); + } + + public function pathStart(): string + { + return route('tokens.servers.start', [$this->token, $this->network, $this]); + } + + public function pathStop(): string + { + return route('tokens.servers.stop', [$this->token, $this->network, $this]); + } + + public function pathReboot(): string + { + return route('tokens.servers.reboot', [$this->token, $this->network, $this]); + } + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted() : void + { + static::deleting(function (self $server) { + $server->tasks()->delete(); + }); + + static::creating(function (self $server) { + $server->user_password = PasswordGenerator::make(length: 32); + $server->sudo_password = PasswordGenerator::make(length: 32); + }); + } +} diff --git a/app/Domain/Server/Models/ServerProvider.php b/app/Domain/Server/Models/ServerProvider.php new file mode 100644 index 0000000..4766ea5 --- /dev/null +++ b/app/Domain/Server/Models/ServerProvider.php @@ -0,0 +1,79 @@ + 'array']; + + protected array $encryptedExtraAttributes = ['accessToken', 'accessKey']; + + protected $withCount = ['servers']; + + public function user() : ?User + { + return User::where('id', $this->getMetaAttribute(ServerAttributeEnum::CREATOR))->first(); + } + + public function token(): BelongsTo + { + return $this->belongsTo(Token::class); + } + + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + public function plans(): BelongsToMany + { + return $this->belongsToMany(ServerProviderPlan::class); + } + + public function regions(): BelongsToMany + { + return $this->belongsToMany(ServerProviderRegion::class); + } + + public function images(): BelongsToMany + { + return $this->belongsToMany(ServerProviderImage::class); + } + + public function client(): ServerProviderClient + { + return ServerProviderClientFactory::make($this); + } + + public function allIndexed(): bool + { + $hasPlans = $this->plans->count() >= 1; + $hasRegions = $this->regions->count() >= 1; + $hasImages = $this->images->count() >= 1; + + return $hasPlans && $hasRegions && $hasImages; + } +} diff --git a/app/Domain/Server/Models/ServerProviderImage.php b/app/Domain/Server/Models/ServerProviderImage.php new file mode 100644 index 0000000..f5dc550 --- /dev/null +++ b/app/Domain/Server/Models/ServerProviderImage.php @@ -0,0 +1,24 @@ +belongsToMany(ServerProvider::class); + } + + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } +} diff --git a/app/Domain/Server/Models/ServerProviderPlan.php b/app/Domain/Server/Models/ServerProviderPlan.php new file mode 100644 index 0000000..1e72f9a --- /dev/null +++ b/app/Domain/Server/Models/ServerProviderPlan.php @@ -0,0 +1,44 @@ + 'array']; + + public function serverProvider(): BelongsToMany + { + return $this->belongsToMany(ServerProvider::class); + } + + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + public function getFormattedMemoryAttribute(): string + { + if ($this->memory < 1024) { + return $this->memory.'MB'; + } + + return round($this->memory / 1024, 0).'GB'; + } + + protected static function booted() + { + static::addGlobalScope( + 'resources', + fn (Builder $builder) => $builder->orderBy('cores')->orderBy('disk')->orderBy('memory') + ); + } +} diff --git a/app/Domain/Server/Models/ServerProviderRegion.php b/app/Domain/Server/Models/ServerProviderRegion.php new file mode 100644 index 0000000..f74e361 --- /dev/null +++ b/app/Domain/Server/Models/ServerProviderRegion.php @@ -0,0 +1,24 @@ +belongsToMany(ServerProvider::class); + } + + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } +} diff --git a/app/Domain/Server/Models/ServerTask.php b/app/Domain/Server/Models/ServerTask.php new file mode 100644 index 0000000..755d717 --- /dev/null +++ b/app/Domain/Server/Models/ServerTask.php @@ -0,0 +1,123 @@ + 'array', + 'script' => 'encrypted', + ]; + + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + public function isSuccessful(): bool + { + return $this->exit_code === 0; + } + + public function isPending(): bool + { + $lastStatus = $this->status(); + + return $lastStatus !== null && ServerTaskStatusEnum::isPending($lastStatus->name); + } + + public function isRunning(): bool + { + $lastStatus = $this->status(); + + return $lastStatus !== null && ServerTaskStatusEnum::isRunning($lastStatus->name); + } + + public function hasFailed(): bool + { + $lastStatus = $this->status(); + + return $lastStatus !== null && ServerTaskStatusEnum::isFailed($lastStatus->name); + } + + public function markAsRunning(): void + { + $this->setStatus(ServerTaskStatusEnum::RUNNING); + } + + public function markAsTimedOut(string $output = ''): self + { + $this->setStatus(ServerTaskStatusEnum::TIMEOUT); + + $this->server->setStatus('failed'); + + return tap($this)->update([ + 'exit_code' => 1, + 'output' => $output, + ]); + } + + public function markAsFinished(int $exitCode = 0, string $output = ''): self + { + $this->setStatus(ServerTaskStatusEnum::FINISHED); + + return tap($this)->update([ + 'exit_code' => $exitCode, + 'output' => $output, + ]); + } + + public function markAsFailed(int $exitCode = 0, string $output = ''): self + { + $this->setStatus(ServerTaskStatusEnum::FAILED); + + $this->server->setStatus('failed'); + + return tap($this)->update([ + 'exit_code' => $exitCode, + 'output' => $output, + ]); + } + + public function run(): self + { + $this->markAsRunning(); + + $shell = new SecureShell($this); + + return $this->user === 'root' ? $shell->run() : $shell->runWithUser(); + } + + public function ipAddress(): string + { + return $this->server->ip_address ?? ''; + } + + public function port(): int + { + return 22; + } + + public function ownerKeyPath(): string + { + return SecureShellKey::storeFor($this->server->token); + } +} diff --git a/app/Domain/Server/Policies/ServerPolicy.php b/app/Domain/Server/Policies/ServerPolicy.php new file mode 100644 index 0000000..8760bc2 --- /dev/null +++ b/app/Domain/Server/Policies/ServerPolicy.php @@ -0,0 +1,60 @@ +onToken($server->token); + } + + public function view(User $user, Server $server): bool + { + return $user->onToken($server->token); + } + + public function create(User $user, Token $token): bool + { + return $token->allows($user, 'server:create'); + } + + public function update(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:update'); + } + + public function delete(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:delete'); + } + + public function start(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:start'); + } + + public function stop(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:stop'); + } + + public function restart(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:restart'); + } + + public function rename(User $user, Server $server): bool + { + return $server->token->allows($user, 'server:rename'); + } +} diff --git a/app/Domain/Server/Policies/ServerProviderPolicy.php b/app/Domain/Server/Policies/ServerProviderPolicy.php new file mode 100644 index 0000000..03f457f --- /dev/null +++ b/app/Domain/Server/Policies/ServerProviderPolicy.php @@ -0,0 +1,40 @@ +onToken($serverProvider->token); + } + + public function view(User $user, ServerProvider $serverProvider): bool + { + return $user->onToken($serverProvider->token); + } + + public function create(User $user, Token $token): bool + { + return $token->allows($user, 'server-provider:create'); + } + + public function update(User $user, ServerProvider $serverProvider): bool + { + return $serverProvider->token->allows($user, 'server-provider:update'); + } + + public function delete(User $user, ServerProvider $serverProvider): bool + { + return $serverProvider->token->allows($user, 'server-provider:delete'); + } +} diff --git a/app/Domain/Server/Services/Providers/AWS.php b/app/Domain/Server/Services/Providers/AWS.php new file mode 100644 index 0000000..eea40ad --- /dev/null +++ b/app/Domain/Server/Services/Providers/AWS.php @@ -0,0 +1,367 @@ +client = new Ec2Client([ + 'credentials' => [ + 'key' => $serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_KEY), + 'secret' => $serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN), + ], + 'region' => config('aws.region'), + 'version' => config('aws.version'), + ]); + } + + /** + * Validate the access token. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html + * + * @return bool + */ + public function valid(): bool + { + try { + $this->client->describeInstances(); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Create a new server. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html + * + * @param ServerModel $serverToBeCreated + * + * @return Server + */ + public function create(ServerModel $serverToBeCreated): Server + { + $server = $this->client->runInstances([ + 'ImageId' => config('aws.imageIds.ubuntu-18-04-lts'), + 'MinCount' => 1, + 'MaxCount' => 1, + 'InstanceType' => $serverToBeCreated->plan->uuid, + ])->get('Instances'); + + return $this->server($server['InstanceId']); + } + + /** + * Retrieve the server for the given ID. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html + * + * @param int $id + * + * @return Server + */ + public function server($id): Server + { + $server = $this->client->describeInstances([ + 'Filter1.Name' => 'instance-id', + 'Filter1.Value' => $id, + ])->get('Reservations')[0]['Instances'][0]; + + $instanceType = $this->client->describeInstanceTypes([ + 'InstanceTypes' => [$server['InstanceType']], + ])->get('InstanceTypes')[0]; + + return new Server([ + 'id' => Arr::get($server, 'InstanceId'), + 'name' => Arr::get($server, 'InstanceType'), + 'plan' => Arr::get($server, 'InstanceType'), + 'memory' => (int) Arr::get($instanceType, 'MemoryInfo.SizeInMiB'), + 'cores' => (int) Arr::get($instanceType, 'VCpuInfo.DefaultVCpus'), + 'disk' => (int) Arr::get($instanceType, 'InstanceStorageInfo.TotalSizeInGB') * 1024, + 'region' => Arr::get($server, 'Placement.AvailabilityZone'), + 'status' => Arr::get($server, 'State.Name'), + 'remoteAddress' => Arr::get($server, 'NetworkInterfaces.0.Association.PublicIp'), + ]); + } + + /** + * Delete the server for the given ID. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_TerminateInstances.html + * + * @param int $id + * + * @return bool + */ + public function delete(int $id): bool + { + try { + $this->client->terminateInstances(['InstanceIds' => [$id]]); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Rename the server for the given ID. + * + * @see @TODO + * + * @param int $id + * @param string $name + * + * @return bool + */ + public function rename(int $id, string $name): bool + { + // @TODO: Implement this + + return true; + } + + /** + * Start the server for the given ID.. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StartInstances.html + * + * @param int $id + * + * @return bool + */ + public function start(int $id): bool + { + try { + $this->client->startInstances(['InstanceIds' => [$id]]); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Stop the server for the given ID. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StopInstances.html + * + * @param int $id + * + * @return bool + */ + public function stop(int $id): bool + { + try { + $this->client->stopInstances(['InstanceIds' => [$id]]); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Reboot the server for the given ID. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RebootInstances.html + * + * @param int $id + * + * @return bool + */ + public function reboot(int $id): bool + { + try { + $this->client->rebootInstances(['InstanceIds' => [$id]]); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Get all available plans. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html + * + * @throws UnknownProperties + */ + public function plans(): PlanCollection + { + $nextToken = null; + + $plans = []; + + do { + $response = $this->client->describeInstanceTypes(array_filter(['NextToken' => $nextToken])); + + $plans = array_merge($plans, $response->get('InstanceTypes')); + + $nextToken = $response->get('NextToken'); + } while ($nextToken); + + return new PlanCollection( + items: collect($plans) + ->transform(fn ($plan): Plan => new Plan([ + 'id' => $plan['InstanceType'], + 'disk' => (int) Arr::get($plan, 'InstanceStorageInfo.TotalSizeInGB') * 1024, + 'memory' => (int) Arr::get($plan, 'MemoryInfo.SizeInMiB'), + 'cores' => (int) Arr::get($plan, 'VCpuInfo.DefaultVCpus'), + 'regions' => [config('aws.region')], + ]))->toArray() + ); + } + + /** + * Get all available regions. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeRegions.html + * + * @throws UnknownProperties + */ + public function regions(): RegionCollection + { + /** @var array> */ + $array = $this->client->describeRegions()->get('Regions'); + + $regions = collect($array)->where('OptInStatus', 'opt-in-not-required'); + + return new RegionCollection( + items: $regions->map(fn (array $region): Region => new Region([ + 'id' => $region['RegionName'], + 'name' => $region['Endpoint'], + ]))->toArray() + ); + } + + /** + * Get all available images. + * + * @see https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html + * + * @throws UnknownProperties + */ + public function images(): ImageCollection + { + // TODO : To implement + return new ImageCollection([]); + } + + /** + * Add an SSH key to the account. + * + * @see TBD + * + * @param string $name + * @param string $publicKey + * + * @return SecureShellKey + */ + public function createSecureShellKey(string $name, string $publicKey): SecureShellKey + { + /* @phpstan-ignore-next-line */ + return $this->client->request('post', '/account/keys', [ + 'name' => config('app.name'), + 'public_key' => $publicKey, + ])['ssh_key']['id']; + } + + /** + * Attempt to find an SSH key on the account. + * + * @see https://developers.digitalocean.com/documentation/v2/#list-all-keys + * + * @return SecureShellKey + */ + public function findSecureShellKey(string $publicKey): SecureShellKey + { + // @phpstan-ignore-next-line + $response = $this->client->request('get', '/account/keys'); + + // @phpstan-ignore-next-line + $response = collect($response)->first(fn ($key) => $key['public_key'] === trim($publicKey))['ssh_key']; + + return new SecureShellKey([ + 'id' => $response['id'], + 'name' => $response['name'], + ]); + } + + /** + * Remove an SSH key from the account. + * + * @see TBD + * + * @param string $id + * + * @return bool + */ + public function deleteSecureShellKey(string $id): bool + { + try { + /* @phpstan-ignore-next-line */ + $this->client->request('delete', "/account/keys/{$this->serverProvider->provider_key_id}"); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Get the image identifier. + * + * @return string + */ + public function getImageId(): string + { + return 'Ubuntu 18.04 x64'; + } + + /** + * Returns an instanciable Rule class for validate the server name. + * + * @return string + */ + public static function nameValidator(): string + { + return ValidAWSServerName::class; + } +} diff --git a/app/Domain/Server/Services/Providers/AWSExceptionHandler.php b/app/Domain/Server/Services/Providers/AWSExceptionHandler.php new file mode 100644 index 0000000..b4875d2 --- /dev/null +++ b/app/Domain/Server/Services/Providers/AWSExceptionHandler.php @@ -0,0 +1,25 @@ +exception; + } +} diff --git a/app/Domain/Server/Services/Providers/DigitalOcean.php b/app/Domain/Server/Services/Providers/DigitalOcean.php new file mode 100644 index 0000000..fd00008 --- /dev/null +++ b/app/Domain/Server/Services/Providers/DigitalOcean.php @@ -0,0 +1,392 @@ +request('get', 'account'); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Create a new server. + * + * @see https://developers.digitalocean.com/documentation/v2/#create-a-new-droplet + * + * @param ServerModel $serverToBeCreated + * + * @return Server + */ + public function create(ServerModel $serverToBeCreated): Server + { + $image = ServerProviderImage::where('uuid', $this->getImageId())->firstOrFail(); + + $server = $this->request('post', 'droplets', [ + 'name' => Str::slug($serverToBeCreated->name), + 'region' => $serverToBeCreated->region->uuid, + 'size' => $serverToBeCreated->plan->uuid, + 'image' => $image->uuid, + 'backups' => false, + 'ipv6' => false, + 'private_networking' => false, + 'monitoring' => false, + 'ssh_keys' => [$this->findSecureShellKey((string) $serverToBeCreated->serverProvider->provider_key_id)->id], + ])['droplet']; + + return $this->server($server['id']); + } + + /** + * Retrieve the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-droplet-by-id + * + * @param int $id + * + * @return Server + */ + public function server(int $id): Server + { + $server = $this->request('get', 'droplets/'.$id)['droplet']; + + /** @var array> */ + $response = Arr::get($server, 'networks.v4'); + + /** @var array */ + $network = collect($response)->firstWhere('type', 'public'); + + return new Server([ + 'id' => Arr::get($server, 'id'), + 'name' => Arr::get($server, 'name'), + 'plan' => Arr::get($server, 'size_slug'), + 'memory' => (int) Arr::get($server, 'memory'), + 'cores' => (int) Arr::get($server, 'vcpus'), + 'disk' => (int) Arr::get($server, 'disk'), + 'region' => Arr::get($server, 'region.slug'), + 'status' => Arr::get($server, 'status'), + 'remoteAddress' => Arr::get($network, 'ip_address'), + 'image' => Arr::get($server, 'image.slug'), + ]); + } + + /** + * Delete the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#delete-a-droplet + * + * @param int $id + * + * @return bool + */ + public function delete(int $id): bool + { + try { + $this->request('delete', 'droplets/'.$id); + } catch (ServerNotFound $exception) { + // Server was already deleted by the user. Nothing to do. + } + + return true; + } + + /** + * Rename the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#rename-a-droplet + * + * @param int $id + * @param string $name + * + * @return bool + */ + public function rename(int $id, string $name): bool + { + $this->request('post', 'droplets/'.$id.'/actions', [ + 'type' => 'rename', + 'name' => $name, + ]); + + return true; + } + + /** + * Start the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#power-on-a-droplet + * + * @param int $id + * + * @return bool + */ + public function start(int $id): bool + { + $this->request('post', 'droplets/'.$id.'/actions', ['type' => 'power_on']); + + return true; + } + + /** + * Stop the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#power-off-a-droplet + * + * @param int $id + * + * @return bool + */ + public function stop(int $id): bool + { + $this->request('post', 'droplets/'.$id.'/actions', ['type' => 'power_off']); + + return true; + } + + /** + * Reboot the server for the given ID. + * + * @see https://developers.digitalocean.com/documentation/v2/#reboot-a-droplet + * + * @param int $id + * + * @return bool + */ + public function reboot(int $id): bool + { + $this->request('post', 'droplets/'.$id.'/actions', ['type' => 'reboot']); + + return true; + } + + /** + * Get all available plans. + * + * @see https://developers.digitalocean.com/documentation/v2/#list-all-sizes + * + * @throws UnknownProperties + */ + public function plans(): PlanCollection + { + /** @var array> */ + $array = Arr::get($this->request('get', 'sizes'), 'sizes', []); + $plans = collect($array)->where('available', true); + + return new PlanCollection( + items: $plans->map(fn (array $plan): Plan => new Plan([ + 'id' => $plan['slug'], + 'disk' => (int) $plan['disk'], + 'memory' => (int) $plan['memory'], + 'cores' => (int) $plan['vcpus'], + 'regions' => $plan['regions'], + ]))->toArray() + ); + } + + /** + * Get all available regions. + * + * @see https://developers.digitalocean.com/documentation/v2/#list-all-regions + * + * @throws UnknownProperties + */ + public function regions(): RegionCollection + { + /** @var array> */ + $array = Arr::get($this->request('get', 'regions'), 'regions', []); + $regions = collect($array)->where('available', true); + + return new RegionCollection( + items: $regions->map(fn (array $region): Region => new Region([ + 'id' => $region['slug'], + 'name' => $region['name'], + ]))->toArray() + ); + } + + /** + * Get all available images. + * + * @see https://developers.digitalocean.com/documentation/v2/#images + * + * @throws UnknownProperties + */ + public function images(): ImageCollection + { + /** @var array> */ + $images = Arr::get($this->request('get', 'images', ['type' => 'distribution']), 'images', []); + + return new ImageCollection( + items: collect($images) + ->map(fn (array $image): Image => new Image([ + 'id' => $image['slug'] ?? $image['id'], + 'name' => $image['name'], + ]))->toArray() + ); + } + + /** + * Add an SSH key to the account. + * + * @see https://developers.digitalocean.com/documentation/v2/#create-a-new-key + * + * @param string $name + * @param string $publicKey + * + * @return SecureShellKey + */ + public function createSecureShellKey(string $name, string $publicKey): SecureShellKey + { + $response = $this->request('post', '/account/keys', [ + 'name' => $name, + 'public_key' => $publicKey, + ])['ssh_key']; + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['public_key'], + ]); + } + + /** + * Attempt to find an SSH key on the account. + * + * @see https://developers.digitalocean.com/documentation/v2/#list-all-keys + * + * @param string $id + * + * @return SecureShellKey + */ + public function findSecureShellKey(string $id): SecureShellKey + { + $response = $this->request('get', "/account/keys/{$id}")['ssh_key']; + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['public_key'], + ]); + } + + /** + * Remove an SSH key from the account. + * + * @see https://developers.digitalocean.com/documentation/v2/#destroy-a-key + * + * @param string $id + * + * @return bool + */ + public function deleteSecureShellKey(string $id): bool + { + $this->request('delete', "/account/keys/{$id}"); + + return true; + } + + /** + * Get the image identifier. + * + * @return string + */ + public function getImageId(): string + { + return 'ubuntu-18-04-x64'; + } + + /** + * Returns an instantiable Rule class for validate the server name. + * + * @return string + */ + public static function nameValidator(): string + { + return ValidDigitalOceanServerName::class; + } + + /** + * Make an HTTP request to DigitalOcean. + * + * @param string $method + * @param string $path + * @param array $parameters + * @throws ServerProviderError + * @throws \Domain\SecureShell\Exceptions\SecureShellKeyAlreadyInUse + * @throws \Domain\Server\Exceptions\ServerLimitExceeded + * @throws \Domain\Server\Exceptions\ServerNotFound + * @return array + */ + private function request(string $method, string $path, array $parameters = []): array + { + try { + $response = Http::withToken($this->token()) + ->withHeaders(['Content-Type' => 'application/json']) + ->send($method, 'https://api.digitalocean.com/v2/'.ltrim($path, '/'), $method === 'get' ? ['query' => $parameters] : ['json' => $parameters]); + + $response->throw(); + + if (in_array($response->status(), [201, 204], true) && $response->body() === '') { + return []; + } + + return $response->json(); + } catch (RequestException $exception) { + return DigitalOceanExceptionHandler::new($exception)->handle(); + } + } + + /** + * Get the authentication token for the provider. + * + * @return string + */ + private function token(): string + { + return $this->serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN); + } +} diff --git a/app/Domain/Server/Services/Providers/DigitalOceanExceptionHandler.php b/app/Domain/Server/Services/Providers/DigitalOceanExceptionHandler.php new file mode 100644 index 0000000..86b8bb5 --- /dev/null +++ b/app/Domain/Server/Services/Providers/DigitalOceanExceptionHandler.php @@ -0,0 +1,87 @@ +exception)) { + $this->handleAuthenticationErrors(); + $this->handleCreate(); + $this->handleServerLookup(); + $this->handleExceptionWithMessage(); + } + + /* @phpstan-ignore-next-line */ + throw $this->exception; + } + + private function handleAuthenticationErrors(): void + { + if ($this->exception instanceof RequestException && $this->exception->response->status() === 401) { + throw new ServerProviderAuthenticationException(); + } + } + + private function handleCreate(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'message'); + + if (Str::contains($error, 'exceed your droplet limit')) { + throw new ServerLimitExceeded(); + } + + if (Str::contains($error, 'SSH Key is already in use')) { + throw new SecureShellKeyAlreadyInUse(); + } + } + } + + private function handleServerLookup(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'message'); + + if (Str::contains($error, 'resource you were accessing could not be found')) { + throw new ServerNotFound(); + } + } + } + + private function handleExceptionWithMessage():void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'message'); + + if ($error !== null) { + throw new ServerProviderError($error); + } + + throw new ServerProviderError(); + } + } +} diff --git a/app/Domain/Server/Services/Providers/Hetzner.php b/app/Domain/Server/Services/Providers/Hetzner.php new file mode 100644 index 0000000..81f576e --- /dev/null +++ b/app/Domain/Server/Services/Providers/Hetzner.php @@ -0,0 +1,397 @@ +request('get', 'locations'); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Create a new server. + * + * @see https://docs.hetzner.cloud/#servers-create-a-server + * + * @param ServerModel $serverToBeCreated + * + * @return Server + */ + public function create(ServerModel $serverToBeCreated): Server + { + $image = ServerProviderImage::where('uuid', $this->getImageId())->firstOrFail(); + + $response = $this->request('post', 'servers', [ + 'name' => Str::slug($serverToBeCreated->name), + 'location' => $serverToBeCreated->region->uuid, + 'server_type' => $serverToBeCreated->plan->uuid, + 'image' => $image->uuid, + 'ssh_keys' => [$this->findSecureShellKey((string) $serverToBeCreated->serverProvider->provider_key_id)->id], + ])['server']; + + return $this->server($response['id']); + } + + /** + * Retrieve the server for the given ID. + * + * @see https://docs.hetzner.cloud/#servers-get-a-server + * + * @param int $id + * + * @return Server + */ + public function server(int $id): Server + { + $server = $this->request('get', 'servers/'.$id)['server']; + + return new Server([ + 'id' => Arr::get($server, 'id'), + 'name' => Arr::get($server, 'name'), + 'plan' => Arr::get($server, 'server_type.id'), + 'memory' => (int) Arr::get($server, 'server_type.memory') * 1024, + 'cores' => (int) Arr::get($server, 'server_type.cores'), + 'disk' => (int) Arr::get($server, 'server_type.disk'), + 'region' => Arr::get($server, 'datacenter.name'), + 'status' => Arr::get($server, 'status'), + 'remoteAddress' => Arr::get($server, 'public_net.ipv4.ip'), + 'image' => Arr::get($server, 'image.name'), + ]); + } + + /** + * Delete the server for the given ID. + * + * @see https://docs.hetzner.cloud/#servers-delete-a-server + * + * @param int $id + * + * @throws ClientException if request fails + * @throws ServerProviderError if response contains an error property + * + * @return bool + */ + public function delete(int $id): bool + { + try { + $response = $this->request('delete', 'servers/'.$id); + + HetznerExceptionHandler::newWithResponse($response)->handle(); + } catch (ServerNotFound $exception) { + // Server was already deleted by the user. Nothing to do. + } + + return true; + } + + /** + * Rename the server for the given ID. + * + * @see https://docs.hetzner.cloud/#servers-update-a-server + * + * @param int $id + * @param string $name + * + * @return bool + */ + public function rename(int $id, string $name): bool + { + $response = $this->request('put', 'servers/'.$id, [ + 'name' => $name, + ]); + + HetznerExceptionHandler::newWithResponse($response)->handle(); + + return true; + } + + /** + * Start the server for the given ID. + * + * @see https://docs.hetzner.cloud/#server-actions-power-on-a-server + * + * @param int $id + * + * @throws ClientException if request fails + * @throws ServerProviderError if response contains an error property + * + * @return bool + */ + public function start(int $id): bool + { + $response = $this->request('post', 'servers/'.$id.'/actions/poweron', ['body' => '{}']); + + HetznerExceptionHandler::newWithResponse($response)->handle(); + + return true; + } + + /** + * Stop the server for the given ID. + * + * @see https://docs.hetzner.cloud/#server-actions-power-off-a-server + * + * @param int $id + * + * @throws ClientException if request fails + * @throws ServerProviderError if response contains an error property + * + * @return bool + */ + public function stop(int $id): bool + { + $response = $this->request('post', 'servers/'.$id.'/actions/poweroff', ['body' => '{}']); + + HetznerExceptionHandler::newWithResponse($response)->handle(); + + return true; + } + + /** + * Reboot the server for the given ID. + * + * @see https://docs.hetzner.cloud/#server-actions-soft-reboot-a-server + * + * @param int $id + * + * @throws ClientException if request fails + * @throws ServerProviderError if response contains an error property + * + * @return bool + */ + public function reboot(int $id): bool + { + $response = $this->request('post', 'servers/'.$id.'/actions/reboot', ['body' => '{}']); + + HetznerExceptionHandler::newWithResponse($response)->handle(); + + return true; + } + + /** + * Get all available plans. + * + * @see https://docs.hetzner.cloud/#server-types-get-all-server-types + * + * @throws UnknownProperties + */ + public function plans(): PlanCollection + { + /** @var array>>> */ + $plans = Arr::get($this->request('get', 'server_types'), 'server_types', []); + + return new PlanCollection( + items: collect($plans) + ->map(fn (array $plan): Plan => new Plan([ + 'id' => $plan['name'], + 'disk' => (int) $plan['disk'], + 'memory' => (int) $plan['memory'] * 1024, + 'cores' => (int) $plan['cores'], + // @phpstan-ignore-next-line + 'regions' => collect($plan['prices'])->pluck('location')->toArray(), + ]))->toArray() + ); + } + + /** + * Get all available regions. + * + * @see https://docs.hetzner.cloud/#locations-get-all-locations + * + * @throws UnknownProperties + */ + public function regions(): RegionCollection + { + /** @var array> */ + $regions = Arr::get($this->request('get', 'locations'), 'locations', []); + + return new RegionCollection( + items: collect($regions) + ->map(fn ($region): Region => new Region([ + 'id' => $region['name'], + 'name' => $region['description'], + ]))->toArray() + ); + } + + /** + * Get all available images. + * + * @see https://docs.hetzner.cloud/#images-get-all-images + * + * @throws UnknownProperties + */ + public function images(): ImageCollection + { + /** @var array> */ + $images = Arr::get($this->request('get', 'images'), 'images', []); + + return new ImageCollection( + items: collect($images) + ->filter(fn ($image) => $image['name'] !== null) + ->map(fn ($image): Image => new Image([ + 'id' => $image['name'], + 'name' => $image['description'], + ]))->toArray() + ); + } + + /** + * Add an SSH key to the account. + * + * @see https://docs.hetzner.cloud/#ssh-keys-create-an-ssh-key + * + * @param string $name + * @param string $publicKey + * + * @return SecureShellKey + */ + public function createSecureShellKey(string $name, string $publicKey): SecureShellKey + { + $response = $this->request('post', '/ssh_keys', [ + 'name' => $name, + 'public_key' => $publicKey, + ])['ssh_key']; + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['public_key'], + ]); + } + + /** + * Attempt to find an SSH key on the account. + * + * @see https://docs.hetzner.cloud/#ssh-keys-get-all-ssh-keys + * + * @param string $id + * + * @return SecureShellKey + */ + public function findSecureShellKey(string $id): SecureShellKey + { + $response = $this->request('get', "/ssh_keys/{$id}")['ssh_key']; + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['public_key'], + ]); + } + + /** + * Remove an SSH key from the account. + * + * @see https://docs.hetzner.cloud/#ssh-keys-delete-an-ssh-key + * + * @param string $id + * + * @return bool + */ + public function deleteSecureShellKey(string $id): bool + { + $this->request('delete', "/ssh_keys/{$id}"); + + return true; + } + + /** + * Get the image identifier. + * + * @return string + */ + public function getImageId(): string + { + return 'ubuntu-18.04'; + } + + /** + * Returns an instantiable Rule class for validate the server name. + * + * @return string + */ + public static function nameValidator(): string + { + return ValidHetznerServerName::class; + } + + /** + * Make an HTTP request to Hetzner. + * + * @param string $method + * @param string $path + * @param array $parameters + */ + private function request(string $method, string $path, array $parameters = []): array + { + try { + $response = Http::withToken($this->token()) + ->send($method, 'https://api.hetzner.cloud/v1/'.ltrim($path, '/'), $method === 'get' ? ['query' => $parameters] : ['json' => $parameters]); + + $response->throw(); + + // Some API calls return a 204 No Content response. + return $response->json() ?? []; + } catch (RequestException $exception) { + return HetznerExceptionHandler::new($exception)->handle(); + } + } + + /** + * Get the authentication token for the provider. + * + * @return string + */ + private function token(): string + { + return $this->serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN); + } +} diff --git a/app/Domain/Server/Services/Providers/HetznerExceptionHandler.php b/app/Domain/Server/Services/Providers/HetznerExceptionHandler.php new file mode 100644 index 0000000..cf7a4a5 --- /dev/null +++ b/app/Domain/Server/Services/Providers/HetznerExceptionHandler.php @@ -0,0 +1,135 @@ +response !== null && count($this->response) > 0) { + $this->handleErrorStatus(); + } + + if (! is_null($this->exception)) { + $this->handleCreate(); + $this->handleCoreLimit(); + $this->handleServerLookup(); + $this->handleAuthentication(); + $this->handleSecureShellKeyConflict(); + $this->handleSecureShellKeyLimitReached(); + $this->handleExceptionWithMessage(); + + /* @phpstan-ignore-next-line */ + throw $this->exception; + } + + return null; + } + + private function handleErrorStatus(): void + { + if ($this->response !== null && Arr::get($this->response, 'action.status') === 'error') { + throw new ServerProviderError(); + } + } + + private function handleCreate(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'error.message'); + + if (Str::contains($error, 'server limit exceeded')) { + throw new ServerLimitExceeded(); + } + } + } + + private function handleAuthentication(): void + { + if ($this->exception instanceof RequestException && $this->exception->response->status() === 401) { + throw new ServerProviderAuthenticationException(); + } + } + + private function handleCoreLimit(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'error.message'); + + if (Str::contains($error, 'core limit exceeded')) { + throw new ServerCoreLimitExceeded(); + } + } + } + + private function handleServerLookup(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'error.code'); + + if (Str::contains($error, 'not_found')) { + throw new ServerNotFound(); + } + } + } + + private function handleSecureShellKeyConflict(): void + { + if ($this->exception instanceof RequestException) { + if ($this->exception->response->status() === 409) { + throw new ServerProviderSecureShellKeyUniqueness(); + } + } + } + + private function handleSecureShellKeyLimitReached(): void + { + if ($this->exception instanceof RequestException) { + if ($this->exception->response->status() === 403) { + throw new ServerProviderSecureShellKeyLimitReached(); + } + } + } + + private function handleExceptionWithMessage():void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'error.message'); + + if ($error !== null) { + throw new ServerProviderError($error); + } + + throw new ServerProviderError(); + } + } +} diff --git a/app/Domain/Server/Services/Providers/Linode.php b/app/Domain/Server/Services/Providers/Linode.php new file mode 100644 index 0000000..2d97e05 --- /dev/null +++ b/app/Domain/Server/Services/Providers/Linode.php @@ -0,0 +1,372 @@ +request('get', 'account'); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Create a new server. + * + * @see https://developers.linode.com/api/v4/linode-instances/#post + * + * @param ServerModel $serverToBeCreated + * + * @return Server + */ + public function create(ServerModel $serverToBeCreated): Server + { + $image = ServerProviderImage::where('uuid', $this->getImageId())->firstOrFail(); + + $response = $this->request('post', 'linode/instances', [ + 'label' => Str::slug($serverToBeCreated->name), + 'region' => $serverToBeCreated->region->uuid, + 'type' => $serverToBeCreated->plan->uuid, + 'image' => $image->uuid, + 'root_pass' => $serverToBeCreated->sudo_password, + 'authorized_keys' => [$this->findSecureShellKey((string) $serverToBeCreated->serverProvider->provider_key_id)->publicKey], + ]); + + return $this->server($response['id']); + } + + /** + * Retrieve the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id + * + * @param int $id + * + * @return Server + */ + public function server(int $id): Server + { + $server = $this->request('get', "linode/instances/{$id}"); + + return new Server([ + 'id' => Arr::get($server, 'id'), + 'name' => Arr::get($server, 'label'), + 'plan' => Arr::get($server, 'type'), + 'memory' => (int) Arr::get($server, 'specs.memory'), + 'cores' => (int) Arr::get($server, 'specs.vcpus'), + 'disk' => (int) Arr::get($server, 'specs.disk'), + 'region' => Arr::get($server, 'region'), + 'status' => Arr::get($server, 'status'), + 'remoteAddress' => Arr::get($server, 'ipv4.0'), + 'image' => Arr::get($server, 'image'), + ]); + } + + /** + * Delete the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id/#delete + * + * @param int $id + * + * @return bool + */ + public function delete(int $id): bool + { + $this->request('delete', 'linode/instances/'.$id); + + return true; + } + + /** + * Rename the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id/#put + * + * @param int $id + * @param string $name + * + * @return bool + */ + public function rename(int $id, string $name): bool + { + $this->request('put', 'linode/instances/'.$id, [ + 'label' => $name, + ]); + + return true; + } + + /** + * Start the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id-boot/#post + * + * @param int $id + * + * @return bool + */ + public function start(int $id): bool + { + $this->request('post', 'linode/instances/'.$id.'/boot'); + + return true; + } + + /** + * Stop the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id-shutdown/#post + * + * @param int $id + * + * @return bool + */ + public function stop(int $id): bool + { + $this->request('post', 'linode/instances/'.$id.'/shutdown'); + + return true; + } + + /** + * Reboot the server for the given ID. + * + * @see https://developers.linode.com/api/v4/linode-instances-linode-id-reboot/#post + * + * @param int $id + * + * @return bool + */ + public function reboot(int $id): bool + { + $this->request('post', 'linode/instances/'.$id.'/reboot'); + + return true; + } + + /** + * Get all available plans. + * + * @see https://developers.linode.com/api/v4/linode-types + * + * @throws UnknownProperties + */ + public function plans(): PlanCollection + { + /** @var array> */ + $plans = Arr::get($this->request('get', 'linode/types'), 'data', []); + + return new PlanCollection( + items: collect($plans) + ->map(fn ($plan): Plan => new Plan([ + 'id' => $plan['id'], + 'disk' => (int) $plan['disk'], + 'memory' => (int) $plan['memory'], + 'cores' => (int) $plan['vcpus'], + 'regions' => [], + ]))->toArray() + ); + } + + /** + * Get all available regions. + * + * @see https://developers.linode.com/api/v4/regions + * + * @throws UnknownProperties + */ + public function regions(): RegionCollection + { + /** @var array> */ + $regions = Arr::get($this->request('get', 'regions'), 'data', []); + + return new RegionCollection( + items: collect($regions) + ->map(fn ($region): Region => new Region([ + 'id' => $region['id'], + 'name' => $region['country'], + ]))->toArray() + ); + } + + /** + * Get all available images. + * + * @see https://developers.linode.com/api/v4/images + * + * @throws UnknownProperties + */ + public function images(): ImageCollection + { + /** @var array> */ + $images = Arr::get($this->request('get', 'images'), 'data', []); + + return new ImageCollection( + items: collect($images) + ->map(fn ($image): Image => new Image([ + 'id' => $image['id'], + 'name' => $image['label'], + ]))->toArray() + ); + } + + /** + * Add an SSH key to the account. + * + * @see https://developers.linode.com/api/v4/profile-sshkeys/#post + * + * @param string $name + * @param string $publicKey + * + * @return SecureShellKey + */ + public function createSecureShellKey(string $name, string $publicKey): SecureShellKey + { + $response = $this->request('post', '/profile/sshkeys', [ + 'label' => $name, + 'ssh_key' => trim($publicKey), + ]); + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['ssh_key'], + ]); + } + + /** + * Attempt to find an SSH key on the account. + * + * @see https://developers.linode.com/api/v4/profile-sshkeys-ssh-key-id + * + * @param string $id + * + * @return SecureShellKey + */ + public function findSecureShellKey(string $id): SecureShellKey + { + $response = $this->request('get', "/profile/sshkeys/{$id}"); + + return new SecureShellKey([ + 'id' => $response['id'], + 'publicKey' => $response['ssh_key'], + ]); + } + + /** + * Remove an SSH key from the account. + * + * @see https://developers.linode.com/api/v4/profile-sshkeys-ssh-key-id/#delete + * + * @param string $id + * + * @return bool + */ + public function deleteSecureShellKey(string $id): bool + { + $this->request('delete', "/profile/sshkeys/{$id}"); + + return true; + } + + /** + * Get the image identifier. + * + * @return string + */ + public function getImageId(): string + { + return 'linode/ubuntu18.04'; + } + + /** + * Returns an instantiable Rule class for validate the server name. + * + * @return string + */ + public static function nameValidator(): string + { + return ValidLinodeServerName::class; + } + + /** + * Make an HTTP request to Linode. + * + * @param string $method + * @param string $path + * @param array $parameters + * + * @return array + */ + private function request(string $method, string $path, array $parameters = []): array + { + try { + $response = Http::withToken($this->token()) + ->withHeaders(['Content-Type' => 'application/json']) + ->send($method, 'https://api.linode.com/v4/'.ltrim($path, '/'), $method === 'get' ? ['query' => $parameters] : ['json' => $parameters]); + + $response->throw(); + + return $response->json(); + } catch (RequestException $exception) { + return LinodeExceptionHandler::new($exception)->handle(); + } + } + + /** + * Get the authentication token for the provider. + * + * @return string + */ + private function token(): string + { + return $this->serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN); + } +} diff --git a/app/Domain/Server/Services/Providers/LinodeExceptionHandler.php b/app/Domain/Server/Services/Providers/LinodeExceptionHandler.php new file mode 100644 index 0000000..69e3e50 --- /dev/null +++ b/app/Domain/Server/Services/Providers/LinodeExceptionHandler.php @@ -0,0 +1,55 @@ +handleCreate(); + $this->handleServerLookup(); + + throw $this->exception; + } + + private function handleCreate(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'errors.0.reason'); + + if (Str::contains($error, 'Account Limit reached')) { + throw new ServerLimitExceeded(); + } + } + } + + private function handleServerLookup(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'errors.0.reason'); + + if (Str::contains($error, 'Not found')) { + throw new ServerNotFound(); + } + } + } +} diff --git a/app/Domain/Server/Services/Providers/Vultr.php b/app/Domain/Server/Services/Providers/Vultr.php new file mode 100644 index 0000000..20481a2 --- /dev/null +++ b/app/Domain/Server/Services/Providers/Vultr.php @@ -0,0 +1,375 @@ +request('get', 'auth/info'); + + return true; + } catch (Throwable) { + return false; + } + } + + /** + * Create a new server. + * + * @see https://www.vultr.com/api/#server_create + * + * @param ServerModel $serverToBeCreated + * + * @return Server + */ + public function create(ServerModel $serverToBeCreated): Server + { + $image = ServerProviderImage::where('uuid', $this->getImageId())->firstOrFail(); + + $response = $this->request('post', 'server/create', [ + 'label' => Str::slug($serverToBeCreated->name), + 'DCID' => $serverToBeCreated->region->uuid, + 'VPSPLANID' => $serverToBeCreated->plan->uuid, + 'OSID' => $image->uuid, + 'SSHKEYID' => $this->findSecureShellKey((string) $serverToBeCreated->serverProvider->provider_key_id)->id, + ]); + + return $this->server((int) $response['SUBID']); + } + + /** + * Retrieve the server for the given ID. + * + * @see https://www.vultr.com/api/#server_server_list + * + * @param int $id + * + * @return Server + */ + public function server(int $id): Server + { + $serverList = $this->request('get', 'server/list'); + + if (! array_key_exists($id, $serverList)) { + throw new ServerNotFound(); + } + + $server = $serverList[$id]; + + $remoteAddress = Arr::get($server, 'main_ip'); + + return new Server([ + 'id' => Arr::get($server, 'SUBID'), + 'name' => Arr::get($server, 'label'), + 'plan' => Arr::get($server, 'VPSPLANID'), + 'memory' => (int) filter_var(Arr::get($server, 'ram'), FILTER_SANITIZE_NUMBER_INT), + 'cores' => (int) filter_var(Arr::get($server, 'vcpu_count'), FILTER_SANITIZE_NUMBER_INT), + 'disk' => (int) filter_var(Arr::get($server, 'disk'), FILTER_SANITIZE_NUMBER_INT), + 'region' => Arr::get($server, 'location'), + 'status' => Arr::get($server, 'status'), + 'remoteAddress' => $remoteAddress === '0.0.0.0' ? null : $remoteAddress, + 'image' => Arr::get($server, 'os'), + ]); + } + + /** + * Delete the server for the given ID. + * + * @see https://www.vultr.com/api/#server_destroy + * + * @param int $id + * + * @return bool + */ + public function delete(int $id): bool + { + $this->request('post', 'server/destroy', ['SUBID' => $id]); + + return true; + } + + /** + * Rename the server for the given ID. + * + * @see https://www.vultr.com/api/#server_label_set + * + * @param int $id + * @param string $name + * + * @return bool + */ + public function rename(int $id, string $name): bool + { + $this->request('post', 'server/label_set', [ + 'SUBID' => $id, + 'label' => $name, + ]); + + return true; + } + + /** + * Start the server for the given ID. + * + * @see https://www.vultr.com/api/#server_start + * + * @param int $id + * + * @return bool + */ + public function start(int $id): bool + { + $this->request('post', 'server/start', ['SUBID' => $id]); + + return true; + } + + /** + * Stop the server for the given ID. + * + * @see https://www.vultr.com/api/#server_halt + * + * @param int $id + * + * @return bool + */ + public function stop(int $id): bool + { + $this->request('post', 'server/halt', ['SUBID' => $id]); + + return true; + } + + /** + * Reboot the server for the given ID. + * + * @see https://www.vultr.com/api/#server_reboot + * + * @param int $id + * + * @return bool + */ + public function reboot(int $id): bool + { + $this->request('post', 'server/reboot', ['SUBID' => $id]); + + return true; + } + + /** + * Get all available plans. + * + * @see https://www.vultr.com/api/#plans_plan_list + * + * @throws UnknownProperties + */ + public function plans(): PlanCollection + { + $plans = $this->request('get', 'plans/list'); + + return new PlanCollection( + items: collect($plans) + ->transform(fn ($plan): Plan => new Plan([ + 'id' => $plan['VPSPLANID'], + 'disk' => (int) $plan['disk'], + 'memory' => (int) $plan['ram'], + 'cores' => (int) $plan['vcpu_count'], + 'regions' => $plan['available_locations'], + ]))->toArray() + ); + } + + /** + * Get all available regions. + * + * @see https://www.vultr.com/api/#regions_region_list + * + * @throws UnknownProperties + */ + public function regions(): RegionCollection + { + $regions = $this->request('get', 'regions/list'); + + return new RegionCollection( + items: collect($regions) + ->transform(fn ($region): Region => new Region([ + 'id' => $region['DCID'], + 'name' => $region['name'], + ]))->toArray() + ); + } + + /** + * Get all available images. + * + * @see https://www.vultr.com/api/#os_os_list + * + * @throws UnknownProperties + */ + public function images(): ImageCollection + { + $images = $this->request('get', 'os/list'); + + return new ImageCollection( + items: collect($images) + ->transform(fn ($image): Image => new Image([ + 'id' => $image['OSID'], + 'name' => $image['name'], + ]))->toArray() + ); + } + + /** + * Add an SSH key to the account. + * + * @see https://www.vultr.com/api/#sshkey_create + * + * @param string $name + * @param string $publicKey + * + * @return SecureShellKey + */ + public function createSecureShellKey(string $name, string $publicKey): SecureShellKey + { + $response = $this->request('post', '/sshkey/create', [ + 'name' => $name, + 'ssh_key' => $publicKey, + ]); + + return new SecureShellKey([ + 'id' => $response['SSHKEYID'], + 'publicKey' => null, + ]); + } + + /** + * Attempt to find an SSH key on the account. + * + * @see https://www.vultr.com/api/#sshkey_sshkey_list + * + * @param string $id + * + * @return SecureShellKey + */ + public function findSecureShellKey(string $id): SecureShellKey + { + $response = $this->request('get', '/sshkey/list'); + $response = collect(array_values($response))->first(fn ($key) => $key['SSHKEYID'] === trim($id)); + + return new SecureShellKey([ + 'id' => $response['SSHKEYID'], + 'publicKey' => $response['ssh_key'], + ]); + } + + /** + * Remove an SSH key from the account. + * + * @see https://www.vultr.com/api/#sshkey_destroy + * + * @param string $id + * + * @return bool + */ + public function deleteSecureShellKey(string $id): bool + { + $this->request('post', '/sshkey/destroy', ['SSHKEYID' => $id]); + + return true; + } + + /** + * Get the image identifier. + * + * @return string + */ + public function getImageId(): string + { + return '270'; //'Ubuntu 18.04 x64'; + } + + /** + * Make an HTTP request to Vultr. + * + * @param string $method + * @param string $path + * @param array $parameters + * + * @return array + */ + public function request(string $method, string $path, array $parameters = []): array + { + try { + $response = Http::withHeaders(['API-Key' => $this->token()]) + ->send($method, 'https://api.vultr.com/v1/'.ltrim($path, '/'), ['form_params' => $parameters]); + + $response->throw(); + + return $response->json(); + } catch (RequestException $exception) { + return VultrExceptionHandler::new($exception)->handle(); + } + } + + /** + * Returns an instantiable Rule class for validate the server name. + * + * @return string + */ + public static function nameValidator(): string + { + return ValidVultrServerName::class; + } + + /** + * Get the authentication token for the provider. + * + * @return string + */ + private function token(): string + { + return $this->serverProvider->getMetaAttribute(ServerAttributeEnum::ACCESS_TOKEN); + } +} diff --git a/app/Domain/Server/Services/Providers/VultrExceptionHandler.php b/app/Domain/Server/Services/Providers/VultrExceptionHandler.php new file mode 100644 index 0000000..2c5524b --- /dev/null +++ b/app/Domain/Server/Services/Providers/VultrExceptionHandler.php @@ -0,0 +1,42 @@ +handleCreate(); + + throw $this->exception; + } + + private function handleCreate(): void + { + if ($this->exception instanceof RequestException) { + $error = Arr::get(json_decode($this->exception->response->body(), true), 'reasonPhrase'); + + if (Str::is($error, 'You have reached the maximum monthly fee limit for this account.')) { + throw new ServerLimitExceeded(); + } + } + } +} diff --git a/app/Domain/Server/Services/ServerProviderClientFactory.php b/app/Domain/Server/Services/ServerProviderClientFactory.php new file mode 100644 index 0000000..56fe62c --- /dev/null +++ b/app/Domain/Server/Services/ServerProviderClientFactory.php @@ -0,0 +1,30 @@ +type) { + ServerProviderTypeEnum::DIGITALOCEAN => new DigitalOcean($serverProvider), + ServerProviderTypeEnum::HETZNER => new Hetzner($serverProvider), + ServerProviderTypeEnum::AWS => new AWS($serverProvider), + ServerProviderTypeEnum::VULTR => new Vultr($serverProvider), + ServerProviderTypeEnum::LINODE => new Linode($serverProvider), + default => throw new InvalidArgumentException(trans('exceptions.invalid_server_provider_type')), + }; + } +} diff --git a/app/Domain/Server/Support/Rules/ValidAWSServerName.php b/app/Domain/Server/Support/Rules/ValidAWSServerName.php new file mode 100644 index 0000000..45a80bc --- /dev/null +++ b/app/Domain/Server/Support/Rules/ValidAWSServerName.php @@ -0,0 +1,35 @@ +properties['user_id']; + } +} diff --git a/app/Domain/Status/Models/Status.php b/app/Domain/Status/Models/Status.php new file mode 100644 index 0000000..701daf8 --- /dev/null +++ b/app/Domain/Status/Models/Status.php @@ -0,0 +1,12 @@ +network; + } + + public function description() : string + { + return ActivityDescriptionEnum::CREATED; + } + + public function causer() : ?Model + { + return $this->network->token; + } + + public function payload() : array + { + return []; + } +} diff --git a/app/Domain/Token/Events/ServerCreated.php b/app/Domain/Token/Events/ServerCreated.php new file mode 100644 index 0000000..a7077fb --- /dev/null +++ b/app/Domain/Token/Events/ServerCreated.php @@ -0,0 +1,44 @@ +server; + } + + public function description() : string + { + return ActivityDescriptionEnum::CREATED; + } + + public function causer() : ?Model + { + return $this->server->token; + } + + public function payload() : array + { + return [ + 'preset' => $this->server->preset, + 'path' => $this->server->pathShow(), + ]; + } +} diff --git a/app/Domain/Token/Events/ServerDeleted.php b/app/Domain/Token/Events/ServerDeleted.php new file mode 100644 index 0000000..a54fce4 --- /dev/null +++ b/app/Domain/Token/Events/ServerDeleted.php @@ -0,0 +1,52 @@ +server = $server; + $this->serverProviderClient = $this->server->serverProvider->client(); + $this->providerServerId = $this->server->provider_server_id; + } + + public function subject() : Model + { + return $this->server; + } + + public function description() : string + { + return ActivityDescriptionEnum::DELETED; + } + + public function causer() : ?Model + { + return $this->server->token; + } + + public function payload() : array + { + return [ + 'preset' => $this->server->preset, + ]; + } +} diff --git a/app/Domain/Token/Events/ServerProviderCreated.php b/app/Domain/Token/Events/ServerProviderCreated.php new file mode 100644 index 0000000..c73bb78 --- /dev/null +++ b/app/Domain/Token/Events/ServerProviderCreated.php @@ -0,0 +1,43 @@ +provider; + } + + public function description() : string + { + return ActivityDescriptionEnum::CREATED; + } + + public function causer() : ?Model + { + return $this->provider->token; + } + + public function payload() : array + { + return [ + 'type' => $this->provider->type, + ]; + } +} diff --git a/app/Domain/Token/Events/ServerProviderDeleted.php b/app/Domain/Token/Events/ServerProviderDeleted.php new file mode 100644 index 0000000..a3b8bb1 --- /dev/null +++ b/app/Domain/Token/Events/ServerProviderDeleted.php @@ -0,0 +1,43 @@ +serverProvider; + } + + public function description() : string + { + return ActivityDescriptionEnum::DELETED; + } + + public function causer() : ?Model + { + return $this->serverProvider->token; + } + + public function payload() : array + { + return [ + 'type' => $this->serverProvider->type, + ]; + } +} diff --git a/app/Domain/Token/Events/ServerProviderUpdated.php b/app/Domain/Token/Events/ServerProviderUpdated.php new file mode 100644 index 0000000..c233f34 --- /dev/null +++ b/app/Domain/Token/Events/ServerProviderUpdated.php @@ -0,0 +1,17 @@ +token; + } + + public function description() : string + { + return ActivityDescriptionEnum::CREATED; + } + + public function causer() : ?Model + { + return $this->token; + } + + public function payload() : array + { + return []; + } +} diff --git a/app/Domain/Token/Events/TokenDeleted.php b/app/Domain/Token/Events/TokenDeleted.php new file mode 100644 index 0000000..38a98fa --- /dev/null +++ b/app/Domain/Token/Events/TokenDeleted.php @@ -0,0 +1,42 @@ +token; + } + + public function description() : string + { + return ActivityDescriptionEnum::DELETED; + } + + public function causer() : ?Model + { + return $this->token; + } + + public function payload() : array + { + return []; + } +} diff --git a/app/Domain/Token/Listeners/ServerCreated/CreateServerOnProvider.php b/app/Domain/Token/Listeners/ServerCreated/CreateServerOnProvider.php new file mode 100644 index 0000000..2055860 --- /dev/null +++ b/app/Domain/Token/Listeners/ServerCreated/CreateServerOnProvider.php @@ -0,0 +1,25 @@ +server; + + CreateServerOnProviderJob::dispatch($server); + } +} diff --git a/app/Domain/Token/Listeners/ServerDeleted/DestroyServerOnServerProvider.php b/app/Domain/Token/Listeners/ServerDeleted/DestroyServerOnServerProvider.php new file mode 100644 index 0000000..a00ad6b --- /dev/null +++ b/app/Domain/Token/Listeners/ServerDeleted/DestroyServerOnServerProvider.php @@ -0,0 +1,28 @@ +providerServerId)) { + return; + } + + DestroyServerOnServerProviderJob::dispatch($event->server, $event->serverProviderClient, $event->providerServerId); + } +} diff --git a/app/Domain/Token/Listeners/ServerDeleted/NotifyUsersOfServerDeletion.php b/app/Domain/Token/Listeners/ServerDeleted/NotifyUsersOfServerDeletion.php new file mode 100644 index 0000000..ae7f6b7 --- /dev/null +++ b/app/Domain/Token/Listeners/ServerDeleted/NotifyUsersOfServerDeletion.php @@ -0,0 +1,36 @@ +notifiables($event->server) + ->each + ->notify(new ServerDeletedNotification($event->server)); + } + + /** + * @param Server $server + * @return Collection + */ + private function notifiables(Server $server) : Collection + { + /** @var Token $token */ + $token = $server->token()->withTrashed()->first(); + + return $server->isProvisioned() ? $token->collaborators : collect([ + $token->user, $server->creator(), + ])->filter()->unique('id')->values(); + } +} diff --git a/app/Domain/Token/Listeners/ServerProviderDeleted/ForgetServerProviderTokenConfiguration.php b/app/Domain/Token/Listeners/ServerProviderDeleted/ForgetServerProviderTokenConfiguration.php new file mode 100644 index 0000000..8eb5dc3 --- /dev/null +++ b/app/Domain/Token/Listeners/ServerProviderDeleted/ForgetServerProviderTokenConfiguration.php @@ -0,0 +1,33 @@ +serverProvider; + + $this->getRelatedTokens($serverProvider)->each->forgetServerConfiguration(); + } + + private function getRelatedTokens(ServerProvider $serverProvider): Collection + { + return Token::where('extra_attributes->'.ServerAttributeEnum::SERVER_CONFIG.'->server_provider_id', $serverProvider->id)->get(); + } +} diff --git a/app/Domain/Token/Listeners/ServerProviderDeleted/TriggerSecureShellKeyRemovalFromServerProvider.php b/app/Domain/Token/Listeners/ServerProviderDeleted/TriggerSecureShellKeyRemovalFromServerProvider.php new file mode 100644 index 0000000..d6f80b0 --- /dev/null +++ b/app/Domain/Token/Listeners/ServerProviderDeleted/TriggerSecureShellKeyRemovalFromServerProvider.php @@ -0,0 +1,23 @@ +serverProvider); + } +} diff --git a/app/Domain/Token/Listeners/ServerProviderUpdated/IndexServerProviderRelatedData.php b/app/Domain/Token/Listeners/ServerProviderUpdated/IndexServerProviderRelatedData.php new file mode 100644 index 0000000..d6c3f1e --- /dev/null +++ b/app/Domain/Token/Listeners/ServerProviderUpdated/IndexServerProviderRelatedData.php @@ -0,0 +1,33 @@ +serverProvider; + + if (! is_null($serverProvider->provider_key_id)) { + IndexServerProviderPlans::dispatch($serverProvider); + + IndexServerProviderRegions::dispatch($serverProvider); + + IndexServerProviderImages::dispatch($serverProvider); + } + } +} diff --git a/app/Domain/Token/Listeners/ServerUpdating/UpdateServerProviderName.php b/app/Domain/Token/Listeners/ServerUpdating/UpdateServerProviderName.php new file mode 100644 index 0000000..2dfb19b --- /dev/null +++ b/app/Domain/Token/Listeners/ServerUpdating/UpdateServerProviderName.php @@ -0,0 +1,49 @@ +server; + + if ($server->provider_server_id !== null && $server->isDirty('name')) { + try { + $server->serverProvider->client()->rename( + $server->provider_server_id, + $server->name, + ); + } catch (Throwable $e) { + if ($e instanceof ServerProviderAuthenticationException) { + $this->notifiables($event)->each->notify(new ServerProviderAuthenticationFailed($server->serverProvider)); + } + + throw $e; + } + } + } + + private function notifiables(ServerUpdating $event) : Collection + { + return collect([ + $event->server->serverProvider->user(), + $event->server->token->user, + ])->filter()->unique('id')->values(); + } +} diff --git a/app/Domain/Token/Listeners/TokenCreated/CreateDefaultNetworks.php b/app/Domain/Token/Listeners/TokenCreated/CreateDefaultNetworks.php new file mode 100644 index 0000000..5d13e94 --- /dev/null +++ b/app/Domain/Token/Listeners/TokenCreated/CreateDefaultNetworks.php @@ -0,0 +1,27 @@ +token->networks()->createMany($this->networks()); + } + + /** + * @return array> + */ + private function networks() : array + { + return collect(static::DEFAULT_NETWORKS)->map(fn (string $network) => [ + 'name' => $network, + ])->toArray(); + } +} diff --git a/app/Domain/Token/Listeners/TokenDeleted/NotifyCollaborators.php b/app/Domain/Token/Listeners/TokenDeleted/NotifyCollaborators.php new file mode 100644 index 0000000..a9413c4 --- /dev/null +++ b/app/Domain/Token/Listeners/TokenDeleted/NotifyCollaborators.php @@ -0,0 +1,23 @@ +token->refresh(); + + if ($event->token->exists) { + $event->token + ->collaborators + ->each + ->notify(new TokenDeletedNotification($event->token)); + } + } +} diff --git a/app/Domain/Token/Listeners/TokenDeleted/PurgeTokenResources.php b/app/Domain/Token/Listeners/TokenDeleted/PurgeTokenResources.php new file mode 100644 index 0000000..2065a3e --- /dev/null +++ b/app/Domain/Token/Listeners/TokenDeleted/PurgeTokenResources.php @@ -0,0 +1,19 @@ +token->purge($event->shouldDeleteServers); + } +} diff --git a/app/Domain/Token/Listeners/TokenDeleted/RemoveTokenNotifications.php b/app/Domain/Token/Listeners/TokenDeleted/RemoveTokenNotifications.php new file mode 100644 index 0000000..4937ba9 --- /dev/null +++ b/app/Domain/Token/Listeners/TokenDeleted/RemoveTokenNotifications.php @@ -0,0 +1,16 @@ +token->id)->delete(); + } +} diff --git a/app/Domain/Token/Models/Network.php b/app/Domain/Token/Models/Network.php new file mode 100644 index 0000000..a078192 --- /dev/null +++ b/app/Domain/Token/Models/Network.php @@ -0,0 +1,99 @@ + NetworkCreated::class, + ]; + + public function token(): BelongsTo + { + return $this->belongsTo(Token::class); + } + + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + public function scopeName(Builder $query, string $network): Builder|EloquentModel|null + { + return $query->where('name', $network)->first(); + } + + public function hasGenesis(): bool + { + return $this->servers()->where('preset', 'genesis')->count() > 0; + } + + public function epoch() : ?string + { + return $this->created_at?->toISOString(); + } + + /** + * @throws Exception + */ + public function base58Prefix() : ?int + { + return AddressPrefixes::get(match ($this->name) { + NetworkTypeEnum::MAINNET => $this->token->config['mainnetPrefix'] ?? null, + NetworkTypeEnum::DEVNET => $this->token->config['devnetPrefix'] ?? null, + NetworkTypeEnum::TESTNET => $this->token->config['testnetPrefix'] ?? null, + default => throw new Exception('Unknown NetworkType'), + }); + } + + public function hasProvisionedGenesis(): bool + { + if ($this->hasGenesis()) { + return $this->servers()->where('preset', 'genesis')->first()?->isProvisioned() ?? false; + } + + return false; + } + + public function getGenesis(): Server + { + return $this->servers()->where('preset', 'genesis')->firstOrFail(); + } + + // We use those methods to get faster and more consistent access to commonly used nested URLs. + public function pathShow(): string + { + return route('tokens.show', [$this->token, $this]); + } + + public function configurationPath() : string + { + return hash('sha256', $this->id.$this->name).'.zip'; + } +} diff --git a/app/Domain/Token/Models/Token.php b/app/Domain/Token/Models/Token.php new file mode 100644 index 0000000..b7b6d6e --- /dev/null +++ b/app/Domain/Token/Models/Token.php @@ -0,0 +1,324 @@ + 'array', + 'keypair' => 'array', + 'extra_attributes' => 'array', + 'onboarded_at' => 'datetime', + ]; + + protected $with = ['media']; + + protected $withCount = ['servers', 'serverProviders', 'secureShellKeys']; + + public function purge(bool $removeServersFromProvider = true) : void + { + $this->invitations()->delete(); + $this->statuses()->delete(); + + if ($removeServersFromProvider) { + $this->servers->each->delete(); + } else { + // By not dispatching model events, jobs that delete servers from server provider will not fire... + Server::withoutEvents(function () { + $this->servers->each->delete(); + }); + } + + $this->networks()->delete(); + $this->serverProviders()->delete(); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function coin(): BelongsTo + { + return $this->belongsTo(Coin::class); + } + + public function serverProviders(): HasMany + { + return $this->hasMany(ServerProvider::class); + } + + public function networks(): HasMany + { + return $this->hasMany(Network::class); + } + + public function servers(): HasManyThrough + { + return $this->hasManyThrough(Server::class, Network::class); + } + + public function network(string $name): ?Network + { + return $this->networks()->where('name', $name)->first(); + } + + public function invitations(): HasMany + { + return $this->hasMany(Invitation::class); + } + + public function collaborators(): BelongsToMany + { + return $this + ->belongsToMany(User::class, 'token_users', 'token_id', 'user_id') + ->using(Collaborator::class) + ->withPivot(['role', 'permissions', 'created_at']); + } + + public function hasCollaborator(User $user) : bool + { + return $this->collaborators->contains($user) || $user->is($this->user); + } + + public function secureShellKeys(): BelongsToMany + { + return $this->belongsToMany(SecureShellKey::class); + } + + public function getSlugOptions(): SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('name') + ->saveSlugsTo('slug') + ->slugsShouldBeNoLongerThan(250); // 255 but room for suffix + } + + public function canBeEdited(): bool + { + return $this->servers_count === 0; + } + + public function shareWith(User $user, string $role = 'collaborator', array $permissions = []): void + { + $this->collaborators()->detach($user); + + $this->collaborators()->attach($user, [ + 'role' => $role, + 'permissions' => $permissions, + ]); + + unset($this->collaborators); + } + + public function stopSharingWith(User $user): void + { + $this->collaborators()->detach($user); + + unset($this->collaborators); + } + + public function getLogoAttribute(): string + { + return Cache::rememberForever( + "tokens.{$this->id}.logo", + fn () => $this->getFirstMediaUrl('logo') + ); + } + + public function registerMediaCollections(): void + { + $this->addMediaCollection('logo')->singleFile(); + } + + public function hasSecureShellKeys(): bool + { + return $this->secure_shell_keys_count > 0; + } + + public function hasServerProviders(): bool + { + return $this->server_providers_count > 0; + } + + public function needsServerConfiguration(): bool + { + return $this->servers_count === 0 && ! $this->hasServerConfiguration(); + } + + public function hasServers(): bool + { + return $this->servers_count > 0; + } + + public function hasProvisionedGenesisServer(): bool + { + return Cache::rememberForever("tokens.{$this->id}.hasProvisionedGenesisServer", function (): bool { + return $this + ->servers() + ->where('preset', PresetTypeEnum::GENESIS) + ->whereNotNull('provisioned_at') + ->whereHas('statuses', fn (Builder $query) => $query->where('name', ServerDeploymentStatus::PROVISIONED)) + ->count() > 0; + }); + } + + public function onboarding(): OnboardingManager + { + return new OnboardingManager($this); + } + + public function setKeypair(array $keypair): void + { + $keypair['privateKey'] = encrypt($keypair['privateKey']); + $this->keypair = $keypair; + $this->save(); + } + + public function getPrivateKey(): string + { + return decrypt($this->keypair['privateKey'] ?? null); + } + + public function availableKeys(): Collection + { + return $this->collaborators + ->map(fn ($collaborator) => $collaborator->secureShellKeys) + ->flatten(); + } + + public function hasAuthorizedKeys(): bool + { + return $this + ->collaborators + ->map(fn ($collaborator) => $collaborator->secureShellKeys->pluck('public_key')) + ->flatten() + ->count() > 0; + } + + public function allows(User $user, string $ability): bool + { + if ($user->ownsToken($this)) { + return true; + } + + try { + $collaborator = $this->collaborators()->where('user_id', $user->id)->firstOrFail(); + + return count(array_intersect($collaborator->pivot->permissions ?? [], ['*', $ability])) > 0; + } catch (Throwable) { + return false; + } + } + + public function getFirstIndexedServerProvider(): ?ServerProvider + { + return $this->serverProviders->filter->allIndexed()->first(); + } + + public function hasAnyIndexedServerProvider(): bool + { + return $this->serverProviders->filter->allIndexed()->count() > 0; + } + + public function getNormalizedTokenAttribute(): string + { + return strtolower($this->config['token'] ?? null); + } + + public function flushCache(): void + { + Cache::forget("tokens.{$this->id}.logo"); + Cache::forget("tokens.{$this->id}.hasProvisionedGenesisServer"); + } + + public function logo() : ?Media + { + return $this->getFirstMedia('logo'); + } + + public function fallbackIdentifier() : ?string + { + return $this->name; + } + + public function hasServerConfiguration(): bool + { + return Arr::get($this->getMetaAttribute(TokenAttributeEnum::SERVER_CONFIG), 'server_provider_id') !== null; + } + + public function forgetServerConfiguration(): void + { + $this->forgetMetaAttribute(TokenAttributeEnum::SERVER_CONFIG); + } + + /** + * Perform any actions required after the model boots. + * + * @return void + */ + protected static function booted() + { + static::created(function (self $token) { + $token->shareWith($token->user, 'owner'); + + $token->setStatus(TokenStatusEnum::PENDING); + }); + } +} diff --git a/app/Domain/Token/Policies/TokenPolicy.php b/app/Domain/Token/Policies/TokenPolicy.php new file mode 100644 index 0000000..2fff036 --- /dev/null +++ b/app/Domain/Token/Policies/TokenPolicy.php @@ -0,0 +1,49 @@ +onToken($token); + } + + public function view(User $user, Token $token): bool + { + return $user->onToken($token); + } + + public function update(User $user, Token $token): bool + { + return $token->allows($user, 'token:update'); + } + + public function delete(User $user, Token $token): bool + { + return $token->allows($user, 'token:delete'); + } + + public function createCollaborator(User $user, Token $token): bool + { + return $token->allows($user, 'collaborator:create'); + } + + public function deleteCollaborator(User $user, Token $token): bool + { + return $token->allows($user, 'collaborator:delete'); + } + + public function manageKeys(User $user, Token $token): bool + { + return $token->allows($user, 'ssh-key:manage'); + } +} diff --git a/app/Domain/Token/Rules/ReservedTokenName.php b/app/Domain/Token/Rules/ReservedTokenName.php new file mode 100644 index 0000000..81412c7 --- /dev/null +++ b/app/Domain/Token/Rules/ReservedTokenName.php @@ -0,0 +1,33 @@ +blacklist = (array) trans('tokens_blacklist'); + } + + public function passes($attribute, $value) + { + return ! collect($this->blacklist) + ->containsStrict($this->normalizeValue($value)); + } + + public function message() + { + return trans('validation.custom.blacklisted'); + } + + private function normalizeValue(string $value): string + { + return (string) Str::of($value)->ascii()->lower(); + } +} diff --git a/app/Domain/Token/Rules/UniqueTokenExtraAttribute.php b/app/Domain/Token/Rules/UniqueTokenExtraAttribute.php new file mode 100644 index 0000000..8be4ed0 --- /dev/null +++ b/app/Domain/Token/Rules/UniqueTokenExtraAttribute.php @@ -0,0 +1,35 @@ +token->serverProviders as $provider) { + if ($provider->getMetaAttribute($attribute) === null || $provider->getMetaAttribute($attribute) === '') { + continue; + } + + if ($provider->getMetaAttribute($attribute) === $value) { + return false; + } + } + + return true; + } + + public function message() + { + return trans('validation.messages.unique_token_extra_attribute'); + } +} diff --git a/app/Domain/User/Models/DatabaseNotification.php b/app/Domain/User/Models/DatabaseNotification.php new file mode 100644 index 0000000..0c3c569 --- /dev/null +++ b/app/Domain/User/Models/DatabaseNotification.php @@ -0,0 +1,67 @@ +id; + $userId = Auth::id(); + $tokenId = $this->data['token']; + + return Cache::remember( + md5("notifications.{$notificationId}.{$userId}.{$tokenId}"), + 300, // 300 seconds + fn () => Token::withTrashed()->findOrFail($tokenId) + ); + } + + public function name(): string + { + return $this->token->name; + } + + public function title(): string + { + return $this->token->name; + } + + public function logo(): string + { + return $this->token->logo; + } + + public function route() : ?string + { + if ($this->relatable_type === Token::class && $this->relatable !== null) { + return route('tokens.details', $this->relatable); + } + + return null; + } + + /** + * Create a new factory instance for the model. + * + * @phpstan-ignore-next-line + * @return DatabaseNotificationFactory + */ + protected static function newFactory() : Factory + { + return new DatabaseNotificationFactory(); + } +} diff --git a/app/Domain/User/Models/User.php b/app/Domain/User/Models/User.php new file mode 100644 index 0000000..0d579c4 --- /dev/null +++ b/app/Domain/User/Models/User.php @@ -0,0 +1,179 @@ + 'array', + 'email_verified_at' => 'datetime', + 'onboarded_at' => 'datetime', + 'last_login_at' => 'datetime', + ]; + + public function ownedTokens() : HasMany + { + return $this->hasMany(Token::class); + } + + public function tokens(): BelongsToMany + { + return $this + ->belongsToMany(Token::class, 'token_users', 'user_id', 'token_id') + ->using(Collaborator::class) + ->withPivot(['role', 'permissions']) + ->whereHas('statuses', fn (Builder $query) => $query->where('name', TokenStatusEnum::FINISHED)); + } + + public function invitations(): HasMany + { + return $this->hasMany(Invitation::class)->orWhere('email', $this->email); + } + + public function secureShellKeys(): HasMany + { + return $this->hasMany(SecureShellKey::class); + } + + public function starredNotifications(): MorphMany + { + return $this->notifications()->where('is_starred', true); + } + + public function hasTokens(): bool + { + return $this->tokens->isNotEmpty(); + } + + public function onToken(Token $token): bool + { + return $token->collaborators->contains($this); + } + + public function ownsToken(Token $token): bool + { + $ownerId = $token->user_id; + + return $ownerId !== 0 && $this->id === $ownerId; + } + + public function roleOn(Token $token): ?string + { + if ($this->tokens->contains($token)) { + // https://github.com/nunomaduro/larastan/issues/515 + /* @phpstan-ignore-next-line */ + return $this->tokens->find($token->id)?->pivot->role; + } + + return null; + } + + public function permissionsOn(Token $token): ?array + { + if ($this->tokens->contains($token)) { + // https://github.com/nunomaduro/larastan/issues/515 + /* @phpstan-ignore-next-line */ + return $this->tokens->find($token->id)?->pivot->permissions; + } + + return null; + } + + public function notifications(): MorphMany + { + return $this + ->morphMany(DatabaseNotification::class, 'notifiable') + ->orderBy('created_at', 'desc') + ->orderBy('id'); + } + + public function hasNewNotifications(): bool + { + $latestNotification = $this->notifications()->latest()->first(); + + if ($latestNotification === null || $latestNotification->created_at === null) { + return false; + } + + if ($this->seen_notifications_at === null) { + return true; + } + + return $latestNotification->created_at->isAfter($this->seen_notifications_at); + } + + /** + * @codeCoverageIgnore + */ + public function selectPersonalData(PersonalDataSelection $personalData): void + { + $personalData->add(sprintf('%s.json', Str::slug($this->name)), [ + 'name' => $this->name, + 'email' => $this->email, + ]); + } + + /** + * @codeCoverageIgnore + */ + public function personalDataExportName(): string + { + return 'personal-data-'.Str::slug($this->name).'.zip'; + } + + public function waitingForEmailConfirmation() : bool + { + if ($this->getMetaAttribute('email_to_update') === null) { + return false; + } + + return Carbon::parse( + $this->getMetaAttribute('email_to_update_stored_at') + )->gte(now()->subDay()); + } + + public function sendEmailChangeConfirmationMail(string $email) : void + { + $email = strtolower($email); + + Mail::to($email)->send(new ConfirmEmailChange($email, $this->name)); + + $this->setMetaAttribute('email_to_update', $email); + $this->setMetaAttribute('email_to_update_stored_at', now()->toString()); + } + + /** + * Create a new factory instance for the model. + * + * @return Factory + */ + protected static function newFactory() + { + return new UserFactory(); + } +} diff --git a/app/Domain/User/Observers/UserObserver.php b/app/Domain/User/Observers/UserObserver.php new file mode 100644 index 0000000..e340a7e --- /dev/null +++ b/app/Domain/User/Observers/UserObserver.php @@ -0,0 +1,32 @@ +forceDeleteUserOwnedTokens($user); + $this->deleteUserSecureShellKeys($user); + $this->deleteUserInvitations($user); + } + + private function forceDeleteUserOwnedTokens(User $user): void + { + $user->ownedTokens()->withTrashed()->get()->each->forceDelete(); + } + + private function deleteUserSecureShellKeys(User $user): void + { + $user->secureShellKeys()->get()->each->delete(); + } + + private function deleteUserInvitations(User $user): void + { + $user->invitations()->get()->each->delete(); + } +} diff --git a/app/Support/AddressPrefixes.php b/app/Support/AddressPrefixes.php new file mode 100644 index 0000000..e8208aa --- /dev/null +++ b/app/Support/AddressPrefixes.php @@ -0,0 +1,79 @@ + 0, + '2' => 3, + '3' => 5, + '4' => 8, + '5' => 10, + '6' => 13, + '7' => 15, + '8' => 18, + '9' => 20, + 'A' => 23, + 'B' => 25, + 'C' => 28, + 'D' => 30, + 'E' => 33, + 'F' => 35, + 'G' => 38, + 'H' => 40, + 'J' => 43, + 'K' => 45, + 'L' => 48, + 'M' => 50, + 'N' => 53, + 'P' => 55, + 'Q' => 58, + 'R' => 60, + 'S' => 63, + 'T' => 65, + 'U' => 68, + 'V' => 70, + 'W' => 73, + 'X' => 75, + 'Y' => 78, + 'Z' => 80, + 'a' => 83, + 'b' => 85, + 'c' => 87, + 'd' => 90, + 'e' => 92, + 'f' => 95, + 'g' => 97, + 'h' => 100, + 'i' => 102, + 'j' => 105, + 'k' => 107, + 'm' => 110, + 'n' => 112, + 'o' => 115, + 'p' => 117, + 'q' => 120, + 'r' => 122, + 's' => 125, + 't' => 127, + 'u' => 130, + 'v' => 132, + 'w' => 135, + 'x' => 137, + 'y' => 140, + 'z' => 142, + ]; + + public static function get(string $prefix): int + { + return static::$prefixes[$prefix]; + } + + public static function valid(string $prefix): bool + { + return array_key_exists($prefix, static::$prefixes); + } +} diff --git a/app/Support/Builders/NotificationBuilder.php b/app/Support/Builders/NotificationBuilder.php new file mode 100644 index 0000000..e8a89e2 --- /dev/null +++ b/app/Support/Builders/NotificationBuilder.php @@ -0,0 +1,100 @@ +content = $this->fromToken( + $invitation->token ?? null, + array_merge($data, ['invitation' => $invitation->id]), + )->getContent(); + + return $this; + } + + public function fromServer(Server $server, array $data, ?Token $token = null): self + { + $this->content = $this->fromToken( + $token ?? $server->token, + array_merge($data, ['server' => $server->id]), + )->getContent(); + + return $this; + } + + public function fromServerProvider(ServerProvider $serverProvider, array $data): self + { + $this->content = $this->fromToken( + $serverProvider->token, + array_merge($data, ['serverProvider' => $serverProvider->id]), + )->getContent(); + + return $this; + } + + public function fromToken(?Token $token, array $data): self + { + $this->content = array_merge($data, [ + 'token' => $token->id ?? null, + 'type' => $this->type, + 'relatable_id' => $token->id ?? null, + 'relatable_type' => Token::class, + ]); + + return $this; + } + + public function withAction(string $title, string $url): self + { + $this->content = array_merge($this->content, ['action' => ['title' => $title, 'url' => $url]]); + + return $this; + } + + public function withUser(User $user): self + { + $this->content = array_merge($this->content, ['user' => $user->id]); + + return $this; + } + + public function success(): self + { + $this->content['type'] = 'success'; + + return $this; + } + + public function danger(): self + { + $this->content['type'] = 'danger'; + + return $this; + } + + public function warning(): self + { + $this->content['type'] = 'warning'; + + return $this; + } + + public function getContent(): array + { + return $this->content; + } +} diff --git a/app/Support/Components/Concerns/HasDefaultRender.php b/app/Support/Components/Concerns/HasDefaultRender.php new file mode 100644 index 0000000..8a83617 --- /dev/null +++ b/app/Support/Components/Concerns/HasDefaultRender.php @@ -0,0 +1,17 @@ +emit('flashMessage', [$message, $type]); + } + + public function toast(string $message, string $type = 'success'): void + { + $this->emit('toastMessage', [$message, $type]); + } +} diff --git a/app/Support/Components/Concerns/InteractsWithPermissions.php b/app/Support/Components/Concerns/InteractsWithPermissions.php new file mode 100644 index 0000000..60d6e62 --- /dev/null +++ b/app/Support/Components/Concerns/InteractsWithPermissions.php @@ -0,0 +1,22 @@ +permissions = Arr::flatten($this->getAvailablePermissionsProperty()); + } + + public function deselectAll(): void + { + $this->permissions = []; + } +} diff --git a/app/Support/Components/Concerns/InteractsWithToken.php b/app/Support/Components/Concerns/InteractsWithToken.php new file mode 100644 index 0000000..3f34699 --- /dev/null +++ b/app/Support/Components/Concerns/InteractsWithToken.php @@ -0,0 +1,18 @@ +token = $token; + } +} diff --git a/app/Support/Components/Concerns/InteractsWithUser.php b/app/Support/Components/Concerns/InteractsWithUser.php new file mode 100644 index 0000000..7e1bf68 --- /dev/null +++ b/app/Support/Components/Concerns/InteractsWithUser.php @@ -0,0 +1,20 @@ + [ + 'transfer' => null, + 'secondSignature' => null, + 'delegateRegistration' => null, + 'vote' => null, + 'multiSignature' => null, + 'ipfs' => null, + 'multiPayment' => null, + 'delegateResignation' => null, + ], + 'dynamic' => [ + 'enabled' => true, + 'minFeePool' => null, + 'minFeeBroadcast' => null, + 'addonBytes' => [ + 'transfer' => null, + 'secondSignature' => null, + 'delegateRegistration' => null, + 'vote' => null, + 'multiSignature' => null, + 'ipfs' => null, + 'multiPayment' => null, + 'delegateResignation' => null, + ], + ], + ]; + + public function mount(Token $tokenObject): void + { + if (is_array($tokenObject->config)) { + $this->fill($tokenObject->config); + } + + $this->tokenObject = $tokenObject; + } + + public function render(): View + { + return view('livewire.manage-token'); + } + + public function updatedConfig(): void + { + $this->validate([ + 'config' => ['required', 'max:1024'], + ]); + + try { + if (! is_string($content = file_get_contents($this->config->getRealPath()))) { + // We'll throw this error to break out of the try catch. We can't test if the NoFileException is thrown + throw new NoFileException(); // @codeCoverageIgnore + } + + $config = Json::parseConfig($content); + + foreach ($config as $key => $value) { + if ($key === 'fees') { + $this->fees = array_merge($this->fees, $value); + } else { + $this->setProtectedPropertyValue($key, $value === 'localhost' ? '127.0.0.1' : $value); + } + } + } catch (Throwable) { + $this->addError('config', 'We were unable to parse the provided config file'); + } + } + + public function updated(string $propertyName): void + { + $this->validateRequest($propertyName); + } + + public function update(): void + { + $data = $this->validateRequest(); + + $this->store($data, true); + } + + public function cancel(): void + { + $this->redirectRoute('home'); + } + + public function store(array $data, bool $final = false): void + { + $this->tokenObject->name = $data['chainName']; + + if ($this->step === 3 && ! $this->fees['dynamic']['enabled']) { + unset($data['fees']['dynamic']['addonBytes']); + } + + $this->tokenObject->config = $data; + + $this->tokenObject->setMetaAttribute(TokenAttributeEnum::REPO_NAME, $this->tokenObject->config['chainName'] ?? null); + + if ($final && TokenStatusEnum::isPending($this->tokenObject->status)) { + // Create the SSH keys for this token... + $this->tokenObject->setKeypair(SecureShellKey::make('')); + + $this->tokenObject->setStatus(TokenStatusEnum::FINISHED); + } + + $this->tokenObject->save(); + + if ($final) { + // Complete the configuration onboarding.... + $this->tokenObject->onboarding()->completeConfiguration(); + + alert('tokens.token_updated', FlashType::SUCCESS); + + $this->redirectRoute('tokens.show', $this->tokenObject); + } + } + + public function next(): void + { + $data = $this->validateRequest(); + + $this->store(array_merge($this->tokenObject->config ?? [], $data)); + + $this->step += 1; + + if ($this->isLastStep()) { + $this->hasReachedReviewStage = true; + } + } + + public function previous(): void + { + $this->step -= 1; + } + + public function isLastStep(): bool + { + return $this->step === 4; + } + + public function setStep(int $step): void + { + if ($step > 0 && $step <= $this->steps) { + $this->step = $step; + } + } + + public function handleDefaults(array $inputs): void + { + $this->inputs = $inputs; + + foreach ($inputs as $input) { + if ($this->getPropertyValue($input) !== '') { + $this->emit('askForConfirmation', false); + + return; + } + } + + $this->setDefaults(); + } + + public function handleFeeDefaults(array $inputs): void + { + $this->inputs = $inputs; + + foreach ($inputs as $input) { + if (! is_null(Arr::get($this->fees, $input))) { + $this->emit('askForConfirmation', true); + + return; + } + } + + $this->setFeeDefaults(); + } + + public function setDefaults(?bool $overwrite = false): void + { + foreach ($this->inputs as $input) { + if ($overwrite === false && $this->getPropertyValue($input)) { + // Skip fields that are already filled in + continue; + } + $this->setProtectedPropertyValue($input, trans('forms.create_token.input_'.Str::snake($input).'_placeholder')); + $this->updated($input); + } + $this->emit('closeModal'); + } + + public function setFeeDefaults(?bool $overwrite = false): void + { + foreach ($this->inputs as $input) { + if ($overwrite === false && ! is_null(Arr::get($this->fees, $input))) { + // Skip fields that are already filled in + continue; + } + Arr::set($this->fees, $input, trans('forms.create_token.'.Str::snake($input).'_placeholder')); + $this->updated($input); + } + $this->emit('closeModal'); + } + + public function returnToReview(): void + { + $data = $this->validateRequest(); + + $this->store(array_merge($this->tokenObject->config ?? [], $data)); + + $this->setStep(4); + } + + public function cancelChanges(): void + { + $this->fill($this->tokenObject->config); + $this->resetErrorBag(); + $this->setStep(4); + } + + private function validateRequest(?string $propertyName = null): array + { + $step1 = $this->step1Rules(); + + $step2 = [ + 'forgers' => ['required', 'integer'], + 'blocktime' => ['required', 'integer'], + 'transactionsPerBlock' => ['required', 'integer'], + 'maxBlockPayload' => ['required', 'integer'], + 'totalPremine' => ['required', 'integer'], + 'rewardHeightStart' => ['required', 'integer'], + 'rewardPerBlock' => ['required', 'integer'], + 'vendorFieldLength' => ['required', 'integer', 'max:255'], + 'wif' => ['required', 'integer', 'max:255'], + 'p2pPort' => ['required', new Port(), ...$this->uniquePortRules('p2pPort')], + 'apiPort' => ['required', new Port(), ...$this->uniquePortRules('apiPort')], + 'webhookPort' => ['required', new Port(), ...$this->uniquePortRules('webhookPort')], + 'monitorPort' => ['required', new Port(), ...$this->uniquePortRules('monitorPort')], + 'coreIp' => ['required', 'ipv4'], + 'explorerIp' => ['required', 'ipv4'], + 'explorerPort' => ['required', new Port(), ...$this->uniquePortRules('explorerPort')], + 'databaseHost' => ['required', 'ipv4'], + 'databasePort' => ['required', new Port(), ...$this->uniquePortRules('databasePort')], + 'databaseName' => ['required', 'max:32'], + ]; + + $step3 = [ + 'fees' => ['required', 'array'], + 'fees.static' => ['required', 'array'], + 'fees.static.transfer' => ['required', 'integer'], + 'fees.static.vote' => ['required', 'integer'], + 'fees.static.secondSignature' => ['required', 'integer'], + 'fees.static.delegateRegistration' => ['required', 'integer'], + 'fees.static.multiSignature' => ['required', 'integer'], + 'fees.static.ipfs' => ['required', 'integer'], + 'fees.static.multiPayment' => ['required', 'integer'], + 'fees.static.delegateResignation' => ['required', 'integer'], + 'fees.dynamic' => ['required', 'array'], + 'fees.dynamic.enabled' => ['required', 'bool'], + 'fees.dynamic.minFeePool' => ['required', 'integer'], + 'fees.dynamic.minFeeBroadcast' => ['required', 'integer'], + 'fees.dynamic.addonBytes' => ['required_if:fees.dynamic.enabled,true', 'array'], + 'fees.dynamic.addonBytes.transfer' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.secondSignature' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.delegateRegistration' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.vote' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.multiSignature' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.ipfs' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.multiPayment' => ['required_if:fees.dynamic.enabled,true|integer'], + 'fees.dynamic.addonBytes.delegateResignation' => ['required_if:fees.dynamic.enabled,true|integer'], + ]; + + $validators = [ + '1' => $step1, + '2' => $step2, + '3' => $step3, + '4' => array_merge($step1, $step2, $step3), + ]; + + if ($propertyName !== null) { + return $this->validateOnly($propertyName, $validators[$this->step]); + } + + return $this->validate($validators[$this->step]); + } + + private function uniquePortRules(string $field) : array + { + return array_values(array_diff([ + 'different:p2pPort', + 'different:apiPort', + 'different:webhookPort', + 'different:monitorPort', + 'different:explorerPort', + 'different:databasePort', + ], ['different:'.$field])); + } +} diff --git a/app/Support/Components/Concerns/Sortable.php b/app/Support/Components/Concerns/Sortable.php new file mode 100644 index 0000000..d9544a2 --- /dev/null +++ b/app/Support/Components/Concerns/Sortable.php @@ -0,0 +1,29 @@ +sortBy === $name) { + if ($this->sortDirection === 'asc') { + $this->sortDirection = 'desc'; + } else { + $this->sortDirection = null; + $this->sortBy = null; + } + } else { + $this->sortBy = $name; + $this->sortDirection = 'asc'; + } + + $this->sortingUpdated(); + } +} diff --git a/app/Support/Components/YoutubeModal.php b/app/Support/Components/YoutubeModal.php new file mode 100644 index 0000000..5bd12e7 --- /dev/null +++ b/app/Support/Components/YoutubeModal.php @@ -0,0 +1,37 @@ + 'showModal', + ]; + + public function mount(string $url): void + { + $this->url = $url; + } + + public function showModal(): void + { + $this->showModal = true; + } + + public function closeModal(): void + { + $this->showModal = false; + } +} diff --git a/app/Support/Eloquent/Concerns/HasSchemalessAttributes.php b/app/Support/Eloquent/Concerns/HasSchemalessAttributes.php new file mode 100644 index 0000000..0eeb742 --- /dev/null +++ b/app/Support/Eloquent/Concerns/HasSchemalessAttributes.php @@ -0,0 +1,67 @@ +encryptedExtraAttributes as $encryptedExtraAttribute) { + $resolvedEncryptedAttribute = $attributes->get($encryptedExtraAttribute); + if (! is_null($resolvedEncryptedAttribute)) { + $attributes->set($encryptedExtraAttribute, decrypt($resolvedEncryptedAttribute)); + } + } + } + + return $attributes; + } + + public function setExtraAttributesAttribute(mixed $value): void + { + /* @phpstan-ignore-next-line */ + if (property_exists($this, 'encryptedExtraAttributes')) { + foreach ($this->encryptedExtraAttributes as $encryptedExtraAttribute) { + if (! is_null(Arr::get($value, $encryptedExtraAttribute))) { + $value[$encryptedExtraAttribute] = encrypt($value[$encryptedExtraAttribute]); + } + } + } + + $this->attributes['extra_attributes'] = json_encode($value); + } + + public function scopeWithExtraAttributes(): Builder + { + return $this->extra_attributes->modelScope(); + } + + public function getMetaAttribute(mixed $name): mixed + { + return $this->extra_attributes->get($name); + } + + public function setMetaAttribute(mixed $name, mixed $value): void + { + $this->extra_attributes->set($name, $value); + + $this->save(); + } + + public function forgetMetaAttribute(mixed $name): void + { + $this->extra_attributes->forget($name); + + $this->save(); + } +} diff --git a/app/Support/Eloquent/Model.php b/app/Support/Eloquent/Model.php new file mode 100644 index 0000000..2d0e39b --- /dev/null +++ b/app/Support/Eloquent/Model.php @@ -0,0 +1,29 @@ +any($abilities, $arguments)) { + return Response::allow(); + } + + throw new AuthorizationException(); + } +} diff --git a/app/Support/Http/Middleware/Authenticate.php b/app/Support/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..7675bd5 --- /dev/null +++ b/app/Support/Http/Middleware/Authenticate.php @@ -0,0 +1,25 @@ +expectsJson()) { + return route('login'); + } + } +} diff --git a/app/Support/Http/Middleware/EncryptCookies.php b/app/Support/Http/Middleware/EncryptCookies.php new file mode 100644 index 0000000..f769c89 --- /dev/null +++ b/app/Support/Http/Middleware/EncryptCookies.php @@ -0,0 +1,18 @@ +check()) { + return redirect(route('tokens')); + } + + return $next($request); + } +} diff --git a/app/Support/Http/Middleware/RedirectIfOnboarding.php b/app/Support/Http/Middleware/RedirectIfOnboarding.php new file mode 100644 index 0000000..4e21a35 --- /dev/null +++ b/app/Support/Http/Middleware/RedirectIfOnboarding.php @@ -0,0 +1,24 @@ +route('token'); + + if ($token->canBeEdited()) { + return redirect(route('tokens.welcome', $token)); + } + + return $next($request); + } +} diff --git a/app/Support/Http/Middleware/ThrottleWithSessionToken.php b/app/Support/Http/Middleware/ThrottleWithSessionToken.php new file mode 100644 index 0000000..859e391 --- /dev/null +++ b/app/Support/Http/Middleware/ThrottleWithSessionToken.php @@ -0,0 +1,50 @@ +resolveRequestSignature($request); + + $maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts); + + if ($this->limiter->tooManyAttempts($key, $maxAttempts)) { + $request->session()->forget('app:auth:id'); + + throw $this->buildException($request, $key, $maxAttempts); + } + + $this->limiter->hit($key, (int) $decayMinutes * 60); + + $response = $next($request); + + return $this->addHeaders( + $response, + $maxAttempts, + $this->calculateRemainingAttempts($key, $maxAttempts) + ); + } +} diff --git a/app/Support/Http/Middleware/TrimStrings.php b/app/Support/Http/Middleware/TrimStrings.php new file mode 100644 index 0000000..2cf86f0 --- /dev/null +++ b/app/Support/Http/Middleware/TrimStrings.php @@ -0,0 +1,20 @@ +mnemonicToEntropy($value); + + return true; + } catch (InvalidArgumentException) { + return false; + } + } + + public function message() + { + return trans('validation.messages.bip39_passphrase'); + } +} diff --git a/app/Support/Rules/Port.php b/app/Support/Rules/Port.php new file mode 100644 index 0000000..c737bb1 --- /dev/null +++ b/app/Support/Rules/Port.php @@ -0,0 +1,20 @@ + 1023 && $value < 65535; + } + + public function message() + { + return trans('validation.messages.port'); + } +} diff --git a/app/Support/Services/ActivityLogger.php b/app/Support/Services/ActivityLogger.php new file mode 100644 index 0000000..8711092 --- /dev/null +++ b/app/Support/Services/ActivityLogger.php @@ -0,0 +1,20 @@ +performedOn($model) + ->causedBy($causer) + ->withProperties(array_merge(['user_id' => $userId ?? Auth::id()], $properties)) + ->log($action); + } +} diff --git a/app/Support/Services/Haiku.php b/app/Support/Services/Haiku.php new file mode 100644 index 0000000..c262676 --- /dev/null +++ b/app/Support/Services/Haiku.php @@ -0,0 +1,217 @@ +token->onboarded_at); + } + + public function fulfilled(): bool + { + foreach ($this->requiredSteps as $step) { + if (! $this->completed($step)) { + return false; + } + } + + return true; + } + + public function completeConfiguration(): void + { + $this->token->setMetaAttribute('onboarding.configuration_completed_at', Carbon::now()); + } + + public function completed(string $name): bool + { + if ($name === TokenOnboardingStatusEnum::CONFIGURATION) { + return $this->token->getMetaAttribute('onboarding.configuration_completed_at') !== null; + } + + if ($name === TokenOnboardingStatusEnum::SERVER_PROVIDERS) { + return $this->completed(TokenOnboardingStatusEnum::CONFIGURATION) + && $this->token->serverProviders()->exists(); + } + + if ($name === TokenOnboardingStatusEnum::SERVER_CONFIGURATION) { + return $this->completed(TokenOnboardingStatusEnum::SERVER_PROVIDERS) + && $this->token->hasServerConfiguration(); + } + + if ($name === TokenOnboardingStatusEnum::SECURE_SHELL_KEYS) { + return $this->completed(TokenOnboardingStatusEnum::SERVER_CONFIGURATION) + && $this->token->secureShellKeys()->exists(); + } + + if ($name === TokenOnboardingStatusEnum::COLLABORATORS) { + return $this->completed(TokenOnboardingStatusEnum::SECURE_SHELL_KEYS) + && $this->token->invitations()->exists(); + } + + return $this->token->servers()->exists(); + } + + public function pending(string $name): bool + { + return ! $this->completed($name); + } + + public function available(string $name): bool + { + if ($this->completed(TokenOnboardingStatusEnum::SERVERS)) { + return true; + } + + if ($name === TokenOnboardingStatusEnum::CONFIGURATION) { + return true; + } + + if ($name === TokenOnboardingStatusEnum::SERVER_PROVIDERS) { + return $this->completed(TokenOnboardingStatusEnum::CONFIGURATION); + } + + if ($name === TokenOnboardingStatusEnum::SERVER_CONFIGURATION) { + return $this->completed(TokenOnboardingStatusEnum::SERVER_PROVIDERS); + } + + if ($name === TokenOnboardingStatusEnum::SECURE_SHELL_KEYS) { + return $this->completed(TokenOnboardingStatusEnum::SERVER_CONFIGURATION); + } + + return $this->completed(TokenOnboardingStatusEnum::SECURE_SHELL_KEYS); + } + + public function isStep(string $title): bool + { + return in_array($title, TokenOnboardingStatusEnum::all(), true); + } +} diff --git a/app/Support/Services/PasswordGenerator.php b/app/Support/Services/PasswordGenerator.php new file mode 100644 index 0000000..d2fbfa4 --- /dev/null +++ b/app/Support/Services/PasswordGenerator.php @@ -0,0 +1,15 @@ +make(Illuminate\Contracts\Console\Kernel::class); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput +); + +/* +|-------------------------------------------------------------------------- +| Shutdown The Application +|-------------------------------------------------------------------------- +| +| Once Artisan has finished running, we will fire off the shutdown events +| so that any final work may be done by the application before we shut +| down the process. This is the last thing to happen to the request. +| +*/ + +$kernel->terminate($input, $status); + +exit($status); diff --git a/banner.png b/banner.png new file mode 100644 index 0000000..ff02ff9 Binary files /dev/null and b/banner.png differ diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..2118ce6 --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,59 @@ +singleton( + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..888b7ab --- /dev/null +++ b/composer.json @@ -0,0 +1,125 @@ +{ + "name": "laravel/laravel", + "type": "project", + "description": "The Laravel Framework.", + "keywords": [ + "framework", + "laravel" + ], + "license": "MIT", + "require": { + "php": "^8.0", + "arkecosystem/crypto": "^1.8", + "arkecosystem/foundation": "^10.6", + "aws/aws-sdk-php": "^3.247", + "bitwasp/bitcoin": "^1.0", + "blade-ui-kit/blade-icons": "^1.4", + "doctrine/dbal": "^3.0", + "fruitcake/laravel-cors": "^3.0", + "huddledigital/zendesk-laravel": "^3.7", + "laravel/framework": "^9.41", + "laravel/horizon": "^5.10", + "laravel/tinker": "^2.7", + "nyholm/psr7": "^1.5", + "predis/predis": "^1.0", + "propaganistas/laravel-fakeid": "^4.0", + "sentry/sentry-laravel": "^2.1", + "spatie/data-transfer-object": "^3.9", + "spatie/laravel-activitylog": "^4.7", + "spatie/laravel-backup": "^8.1", + "spatie/laravel-flash": "^1.9", + "spatie/laravel-medialibrary": "^10.7", + "spatie/laravel-model-status": "^1.11", + "spatie/laravel-personal-data-export": "^4.2", + "spatie/laravel-responsecache": "^7.4", + "spatie/laravel-sluggable": "^3.4", + "staudenmeir/belongs-to-through": "^2.12", + "symfony/psr-http-message-bridge": "^2.1" + }, + "require-dev": { + "barryvdh/laravel-debugbar": "^3.7", + "spatie/laravel-ignition": "^1.6", + "laravel/dusk": "^6.1", + "laravel/sail": "^1.16", + "spatie/phpunit-snapshot-assertions": "^4.2", + "timacdonald/log-fake": "^2.0" + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true, + "allow-plugins": { + "phpstan/extension-installer": true, + "pestphp/pest-plugin": true, + "treeware/plant": true + } + }, + "extra": { + "laravel": { + "dont-discover": [ + "laravel/fortify", + "laravel/telescope" + ] + } + }, + "autoload": { + "psr-4": { + "App\\": "app/App/", + "Domain\\": "app/Domain/", + "Support\\": "app/Support/", + "Database\\Factories\\": "database/factories/", + "Database\\Seeders\\": "database/seeders/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "post-autoload-dump": [ + "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", + "@php artisan package:discover --ansi", + "@php artisan vendor:publish --provider=\"ARKEcosystem\\Foundation\\Providers\\UserInterfaceServiceProvider\" --tag=\"pagination\" --tag=\"images\"" + ], + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "@php artisan key:generate --ansi" + ], + "post-update-cmd": [ + "@php artisan horizon:publish --ansi" + ], + "build": [ + "yarn format", + "yarn prod" + ], + "db:dev": [ + "@php artisan playbook:run DevelopmentPlaybook" + ], + "db:demo": [ + "@php artisan playbook:run DemoPlaybook" + ], + "db:bare": [ + "@php artisan playbook:run BarePlaybook" + ], + "analyse": [ + "vendor/bin/phpstan analyse --memory-limit=2G --configuration vendor/arkecosystem/foundation/phpstan.neon" + ], + "format": [ + "vendor/bin/php-cs-fixer fix --config=vendor/arkecosystem/foundation/.php-cs-fixer.php" + ], + "test": [ + "./vendor/bin/pest" + ], + "test:fast": [ + "./vendor/bin/pest --parallel" + ], + "test:coverage": [ + "./vendor/bin/pest --coverage --min=100 --coverage-html=.coverage --coverage-clover=coverage.xml" + ] + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..3d0528c --- /dev/null +++ b/composer.lock @@ -0,0 +1,17497 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "87170660706c11e28693169bed5d50ce", + "packages": [ + { + "name": "arkecosystem/crypto", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/ArkEcosystem/php-crypto.git", + "reference": "d575bd6dd29725ac6916a4b08d9017dea0637345" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ArkEcosystem/php-crypto/zipball/d575bd6dd29725ac6916a4b08d9017dea0637345", + "reference": "d575bd6dd29725ac6916a4b08d9017dea0637345", + "shasum": "" + }, + "require": { + "bitwasp/bitcoin": "^1.0", + "php": "^7.4|^8.0", + "simplito/elliptic-php": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "graham-campbell/analyzer": "^3.0", + "illuminate/support": "^7.0|^8.0", + "mockery/mockery": "^1.2", + "pestphp/drift": "^0.3", + "pestphp/pest": "^1.0", + "pestphp/pest-plugin-parallel": "^0.3.1", + "phpunit/phpunit": "^9.5", + "symfony/var-dumper": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "ArkEcosystem\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Faust", + "email": "hello@brianfaust.me", + "homepage": "https://github.com/faustbrian" + } + ], + "description": "A simple PHP Cryptography Implementation for the Ark Blockchain.", + "keywords": [ + "api", + "ark", + "blockchain", + "crypto", + "currency" + ], + "support": { + "issues": "https://github.com/ArkEcosystem/php-crypto/issues", + "source": "https://github.com/ArkEcosystem/php-crypto/tree/1.8.0" + }, + "time": "2021-09-24T07:33:57+00:00" + }, + { + "name": "arkecosystem/foundation", + "version": "10.18.2", + "source": { + "type": "git", + "url": "https://github.com/ArkEcosystem/laravel-foundation.git", + "reference": "bdf3f2a410e105e07ecd8d8cba0918c5597d88b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ArkEcosystem/laravel-foundation/zipball/bdf3f2a410e105e07ecd8d8cba0918c5597d88b9", + "reference": "bdf3f2a410e105e07ecd8d8cba0918c5597d88b9", + "shasum": "" + }, + "require": { + "calebporzio/sushi": "^2.4", + "danharrin/livewire-rate-limiting": "^1.0", + "elgigi/commonmark-emoji": "^2.0", + "ergebnis/phpstan-rules": "^1.0", + "fakerphp/faker": "^1.20", + "friendsofphp/php-cs-fixer": "^3.12", + "google/recaptcha": "^1.2", + "graham-campbell/analyzer": "^3.1", + "guzzlehttp/guzzle": "^7.5", + "illuminate/bus": "^9.36", + "illuminate/contracts": "^9.36", + "illuminate/http": "^9.36", + "illuminate/mail": "^9.36", + "illuminate/support": "^9.36", + "illuminate/view": "^9.36", + "jamesmills/laravel-timezone": "^1.11", + "jasonmccreary/laravel-test-assertions": "^2.1", + "jenssegers/agent": "^2.6", + "johnkary/phpunit-speedtrap": "^4.0", + "laravel/fortify": "^1.13", + "laravel/telescope": "^4.9", + "league/commonmark": "^2.3", + "livewire/livewire": "^2.10", + "mockery/mockery": "^1.5", + "nunomaduro/collision": "^6.3", + "nunomaduro/larastan": "^2.2", + "orchestra/testbench": "^7.11", + "pestphp/pest": "^1.22", + "pestphp/pest-plugin-faker": "^1.0", + "pestphp/pest-plugin-laravel": "^1.3", + "pestphp/pest-plugin-livewire": "^1.0", + "pestphp/pest-plugin-parallel": "^1.2", + "php": "^8.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^9.5", + "pragmarx/google2fa-laravel": "^2.0", + "rector/rector": "^0.14", + "ruafozy/mersenne-twister": "^1.3", + "spatie/laravel-flash": "^1.9", + "spatie/laravel-honeypot": "^4.3", + "spatie/laravel-medialibrary": "^10.6", + "spatie/laravel-newsletter": "^4.11", + "spatie/laravel-package-tools": "^1.13", + "spatie/laravel-personal-data-export": "^4.2", + "spatie/laravel-responsecache": "^7.4", + "spatie/laravel-schemaless-attributes": "^2.3", + "spatie/laravel-sluggable": "^3.4", + "spatie/pest-plugin-snapshots": "^1.1", + "spatie/regex": "^3.1", + "spatie/yaml-front-matter": "^2.0" + }, + "require-dev": { + "laravel/nova": "^4.13", + "spatie/laravel-permission": "^5.5", + "vyuldashev/nova-permission": "^3.2" + }, + "suggest": { + "laravel/nova": "Needed for backend management of data", + "spatie/laravel-permission": "Needed for nova permissions & roles", + "vyuldashev/nova-permission": "Needed for nova permissions & roles" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "ARKEcosystem\\Foundation\\Providers\\FoundationServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/UserInterface/helpers.php" + ], + "psr-4": { + "ARKEcosystem\\Foundation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "ItsANameToo", + "email": "itsanametoo@protonmail.com" + } + ], + "description": "User-Interface Scaffolding for Laravel. Powered by Tailwind CSS.", + "support": { + "issues": "https://github.com/ArkEcosystem/laravel-foundation/issues", + "source": "https://github.com/ArkEcosystem/laravel-foundation/tree/10.18.2" + }, + "time": "2022-10-27T14:26:45+00:00" + }, + { + "name": "aws/aws-crt-php", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "3942776a8c99209908ee0b287746263725685732" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/3942776a8c99209908ee0b287746263725685732", + "reference": "3942776a8c99209908ee0b287746263725685732", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.4.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.2" + }, + "time": "2021-09-03T22:57:30+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.247.2", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "00542e760d8464e0ee635f916841fdfbd1ceb95c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/00542e760d8464e0ee635f916841fdfbd1ceb95c", + "reference": "00542e760d8464e0ee635f916841fdfbd1ceb95c", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.2", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "guzzlehttp/promises": "^1.4.0", + "guzzlehttp/psr7": "^1.8.5 || ^2.3", + "mtdowling/jmespath.php": "^2.6", + "php": ">=5.5" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^1.10.22", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "nette/neon": "^2.3", + "paragonie/random_compat": ">= 2", + "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", + "psr/cache": "^1.0", + "psr/simple-cache": "^1.0", + "sebastian/comparator": "^1.2.3 || ^4.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.247.2" + }, + "time": "2022-11-23T19:35:36+00:00" + }, + { + "name": "bacon/bacon-qr-code", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/d70c840f68657ce49094b8d91f9ee0cc07fbf66c", + "reference": "d70c840f68657ce49094b8d91f9ee0cc07fbf66c", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.7" + }, + "time": "2022-03-14T02:02:36+00:00" + }, + { + "name": "bitwasp/bech32", + "version": "v0.0.1", + "source": { + "type": "git", + "url": "https://github.com/Bit-Wasp/bech32.git", + "reference": "e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bit-Wasp/bech32/zipball/e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7", + "reference": "e1ea58c848a4ec59d81b697b3dfe9cc99968d0e7", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.0", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/bech32.php" + ], + "psr-4": { + "BitWasp\\Bech32\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Unlicense" + ], + "authors": [ + { + "name": "Thomas Kerin", + "homepage": "https://thomaskerin.io", + "role": "Author" + } + ], + "description": "Pure (no dependencies) implementation of bech32", + "homepage": "https://github.com/bit-wasp/bech32", + "support": { + "issues": "https://github.com/Bit-Wasp/bech32/issues", + "source": "https://github.com/Bit-Wasp/bech32/tree/more-tests" + }, + "time": "2018-02-05T22:23:47+00:00" + }, + { + "name": "bitwasp/bitcoin", + "version": "1.0.x-dev", + "source": { + "type": "git", + "url": "https://github.com/Bit-Wasp/bitcoin-php.git", + "reference": "670063be60655500a327d5d470d6eba0d77c6941" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bit-Wasp/bitcoin-php/zipball/670063be60655500a327d5d470d6eba0d77c6941", + "reference": "670063be60655500a327d5d470d6eba0d77c6941", + "shasum": "" + }, + "require": { + "bitwasp/bech32": "^0.0.1", + "bitwasp/buffertools": "^0.5.0", + "composer/semver": "^1.4.0|^3.2.0", + "lastguest/murmurhash": "v2.0.0", + "mdanter/ecc": "^0.5.0", + "php-64bit": ">=7.0", + "pleonasm/merkle-tree": "1.0.0" + }, + "require-dev": { + "bitwasp/bitcoinconsensus": "v3.0.0", + "bitwasp/secp256k1-php": "^v0.2.0", + "ext-json": "*", + "nbobtc/bitcoind-php": "v2.0.2", + "phpunit/phpunit": "^5.4.0", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "suggest": { + "ext-bitcoinconsensus": "The bitcoinconsensus library for safest possible script verification", + "ext-secp256k1": "The secp256k1 library for fast and safe elliptic curve operations" + }, + "default-branch": true, + "type": "library", + "autoload": { + "files": [ + "src/Script/functions.php" + ], + "psr-4": { + "BitWasp\\Bitcoin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Unlicense" + ], + "authors": [ + { + "name": "Thomas Kerin", + "homepage": "https://thomaskerin.io", + "role": "Author" + } + ], + "description": "PHP Bitcoin library with functions for transactions, signatures, serialization, Random/Deterministic ECDSA keys, blocks, RPC bindings", + "homepage": "https://github.com/bit-wasp/bitcoin-php", + "support": { + "issues": "https://github.com/Bit-Wasp/bitcoin-php/issues", + "source": "https://github.com/Bit-Wasp/bitcoin-php/tree/1.0" + }, + "time": "2021-01-16T21:13:16+00:00" + }, + { + "name": "bitwasp/buffertools", + "version": "v0.5.7", + "source": { + "type": "git", + "url": "https://github.com/Bit-Wasp/buffertools-php.git", + "reference": "133746d0b514e0016d8479b54aa97475405a9f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bit-Wasp/buffertools-php/zipball/133746d0b514e0016d8479b54aa97475405a9f1f", + "reference": "133746d0b514e0016d8479b54aa97475405a9f1f", + "shasum": "" + }, + "require": { + "php-64bit": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "BitWasp\\Buffertools\\": "src/Buffertools/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Thomas Kerin", + "homepage": "https://thomaskerin.io" + }, + { + "name": "Ruben de Vries", + "email": "ruben@rubensayshi.com" + } + ], + "description": "Toolbox for working with binary and hex data. Similar to NodeJS Buffer.", + "support": { + "issues": "https://github.com/Bit-Wasp/buffertools-php/issues", + "source": "https://github.com/Bit-Wasp/buffertools-php/tree/v0.5.7" + }, + "time": "2020-01-17T21:31:49+00:00" + }, + { + "name": "blade-ui-kit/blade-icons", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/blade-ui-kit/blade-icons.git", + "reference": "977559507feebba431019abf1b319d71dfdacd95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/977559507feebba431019abf1b319d71dfdacd95", + "reference": "977559507feebba431019abf1b319d71dfdacd95", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0", + "illuminate/filesystem": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "illuminate/view": "^8.0|^9.0", + "php": "^7.4|^8.0", + "symfony/console": "^5.3|^6.0", + "symfony/finder": "^5.3|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/blade-icons-generate" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Icons\\BladeIconsServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "BladeUI\\Icons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of icons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-icons", + "keywords": [ + "blade", + "icons", + "laravel", + "svg" + ], + "support": { + "issues": "https://github.com/blade-ui-kit/blade-icons/issues", + "source": "https://github.com/blade-ui-kit/blade-icons" + }, + "funding": [ + { + "url": "https://github.com/caneco", + "type": "github" + }, + { + "url": "https://github.com/driesvints", + "type": "github" + } + ], + "time": "2022-09-30T11:26:24+00:00" + }, + { + "name": "brianium/paratest", + "version": "v6.6.5", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "31fd5d69b41725f383c9a083831eefcc7ecd9061" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/31fd5d69b41725f383c9a083831eefcc7ecd9061", + "reference": "31fd5d69b41725f383c9a083831eefcc7ecd9061", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "jean85/pretty-package-versions": "^2.0.5", + "php": "^7.3 || ^8.0", + "phpunit/php-code-coverage": "^9.2.17", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-timer": "^5.0.3", + "phpunit/phpunit": "^9.5.24", + "sebastian/environment": "^5.1.4", + "symfony/console": "^5.4.12 || ^6.1.4", + "symfony/process": "^5.4.11 || ^6.1.3" + }, + "require-dev": { + "doctrine/coding-standard": "^10.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "infection/infection": "^0.26.14", + "malukenho/mcbumpface": "^1.1.5", + "squizlabs/php_codesniffer": "^3.7.1", + "symfony/filesystem": "^5.4.12 || ^6.1.4", + "vimeo/psalm": "^4.27.0" + }, + "bin": [ + "bin/paratest", + "bin/paratest.bat", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v6.6.5" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2022-10-28T12:22:26+00:00" + }, + { + "name": "brick/math", + "version": "0.10.2", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "4.25.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.10.2" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2022-08-10T22:54:19+00:00" + }, + { + "name": "calebporzio/sushi", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/calebporzio/sushi.git", + "reference": "cec0768285971add48f3ccebfefad856be6f5078" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/calebporzio/sushi/zipball/cec0768285971add48f3ccebfefad856be6f5078", + "reference": "cec0768285971add48f3ccebfefad856be6f5078", + "shasum": "" + }, + "require": { + "illuminate/database": "^5.8 || ^6.0 || ^7.0 || ^8.0 || ^9.0", + "illuminate/support": "^5.8 || ^6.0 || ^7.0 || ^8.0 || ^9.0", + "php": "^7.1.3|^8.0" + }, + "require-dev": { + "doctrine/dbal": "^2.9", + "orchestra/database": "3.8.* || 3.9.* || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "orchestra/testbench": "3.8.* || 3.9.* || ^4.0 || ^6.0 || ^7.0", + "phpunit/phpunit": "^7.5 || ^8.4 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sushi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "Eloquent's missing \"array\" driver.", + "support": { + "source": "https://github.com/calebporzio/sushi/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://github.com/calebporzio", + "type": "github" + } + ], + "time": "2022-01-18T22:48:40+00:00" + }, + { + "name": "clue/stream-filter", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/clue/stream-filter.git", + "reference": "d6169430c7731d8509da7aecd0af756a5747b78e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/d6169430c7731d8509da7aecd0af756a5747b78e", + "reference": "d6169430c7731d8509da7aecd0af756a5747b78e", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/php-stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.6.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-02-21T13:15:14+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-11-17T09:50:14+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "danharrin/livewire-rate-limiting", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/danharrin/livewire-rate-limiting.git", + "reference": "b99facf5b607fb0cde92a6f254f437295339f7de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danharrin/livewire-rate-limiting/zipball/b99facf5b607fb0cde92a6f254f437295339f7de", + "reference": "b99facf5b607fb0cde92a6f254f437295339f7de", + "shasum": "" + }, + "require": { + "illuminate/support": "^8.0|^9.0", + "php": "^8.0" + }, + "require-dev": { + "livewire/livewire": "^2.3", + "orchestra/testbench": "^6.2|^7.0", + "phpunit/phpunit": "^9.4", + "symplify/monorepo-builder": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "DanHarrin\\LivewireRateLimiting\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Harrin", + "email": "dan@danharrin.com" + } + ], + "description": "Apply rate limiters to Laravel Livewire actions.", + "homepage": "https://github.com/danharrin/livewire-rate-limiting", + "support": { + "issues": "https://github.com/danharrin/livewire-rate-limiting/issues", + "source": "https://github.com/danharrin/livewire-rate-limiting" + }, + "funding": [ + { + "url": "https://github.com/danharrin", + "type": "github" + } + ], + "time": "2022-01-21T11:26:58+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.3" + }, + "time": "2020-10-02T16:03:48+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.13.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.3" + }, + "time": "2022-07-02T10:48:51+00:00" + }, + { + "name": "doctrine/cache", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" + }, + { + "name": "doctrine/dbal", + "version": "3.5.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", + "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "10.0.0", + "jetbrains/phpstorm-stubs": "2022.2", + "phpstan/phpstan": "1.8.10", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "9.5.25", + "psalm/plugin-phpunit": "0.17.0", + "squizlabs/php_codesniffer": "3.7.1", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.29.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.5.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2022-10-24T07:26:18+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + }, + "time": "2022-05-02T15:47:09+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.28" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2022-10-12T20:59:15+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.6" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2022-10-20T09:10:12+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-02-28T11:07:21+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-09-10T18:51:20+00:00" + }, + { + "name": "drewm/mailchimp-api", + "version": "v2.5.4", + "source": { + "type": "git", + "url": "https://github.com/drewm/mailchimp-api.git", + "reference": "c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drewm/mailchimp-api/zipball/c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a", + "reference": "c6cdfab4ca6ddbc3b260913470bd0a4a5cb84c7a", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "7.0.*", + "vlucas/phpdotenv": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "DrewM\\MailChimp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Drew McLellan", + "email": "drew.mclellan@gmail.com", + "homepage": "http://allinthehead.com/" + } + ], + "description": "Super-simple, minimum abstraction MailChimp API v3 wrapper", + "homepage": "https://github.com/drewm/mailchimp-api", + "support": { + "issues": "https://github.com/drewm/mailchimp-api/issues", + "source": "https://github.com/drewm/mailchimp-api/tree/master" + }, + "time": "2019-08-06T09:24:58+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f88dcf4b14af14a98ad96b14b2b317969eab6715", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2022-06-18T20:57:19+00:00" + }, + { + "name": "elgigi/commonmark-emoji", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ElGigi/CommonMarkEmoji.git", + "reference": "8e7bf0ecbb719ca7ecc2ecbd27e4a4422ed9ef50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ElGigi/CommonMarkEmoji/zipball/8e7bf0ecbb719ca7ecc2ecbd27e4a4422ed9ef50", + "reference": "8e7bf0ecbb719ca7ecc2ecbd27e4a4422ed9ef50", + "shasum": "" + }, + "require": { + "league/commonmark": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "commonmark-extension", + "autoload": { + "psr-4": { + "ElGigi\\CommonMarkEmoji\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "CommonMark extension adds UTF-8 emoji with Github tag for the `league/commonmark` PHP Markdown parsing engine, based on the CommonMark spec.", + "support": { + "issues": "https://github.com/ElGigi/CommonMarkEmoji/issues", + "source": "https://github.com/ElGigi/CommonMarkEmoji/tree/v2.0.0" + }, + "time": "2021-08-23T11:27:20+00:00" + }, + { + "name": "ergebnis/phpstan-rules", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/phpstan-rules.git", + "reference": "ebeced30d7e50324a94a83c19a59d75816e8fbb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/ebeced30d7e50324a94a83c19a59d75816e8fbb4", + "reference": "ebeced30d7e50324a94a83c19a59d75816e8fbb4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "nikic/php-parser": "^4.2.3", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.0.0" + }, + "require-dev": { + "doctrine/orm": "^2.10.2", + "ergebnis/composer-normalize": "^2.15.0", + "ergebnis/license": "^1.1.0", + "ergebnis/php-cs-fixer-config": "^2.14.0", + "ergebnis/test-util": "^1.5.0", + "infection/infection": "~0.15.3", + "nette/di": "^3.0.11", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-strict-rules": "^1.0.0", + "phpunit/phpunit": "^8.5.21", + "psalm/plugin-phpunit": "~0.16.1", + "psr/container": "^1.0.0", + "vimeo/psalm": "^4.12.0", + "zendframework/zend-servicemanager": "^2.0.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\PHPStan\\Rules\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com" + } + ], + "description": "Provides additional rules for phpstan/phpstan.", + "homepage": "https://github.com/ergebnis/phpstan-rules", + "keywords": [ + "PHPStan", + "phpstan-extreme-rules", + "phpstan-rules" + ], + "support": { + "issues": "https://github.com/ergebnis/phpstan-rules/issues", + "source": "https://github.com/ergebnis/phpstan-rules" + }, + "funding": [ + { + "url": "https://github.com/localheinz", + "type": "github" + } + ], + "time": "2021-11-08T15:37:09+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/37f751c67a5372d4e26353bd9384bc03744ec77b", + "reference": "37f751c67a5372d4e26353bd9384bc03744ec77b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "symfony/phpunit-bridge": "^4.4 || ^5.2" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "v1.20-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.20.0" + }, + "time": "2022-07-20T13:12:54+00:00" + }, + { + "name": "fgrosse/phpasn1", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/fgrosse/PHPASN1.git", + "reference": "eef488991d53e58e60c9554b09b1201ca5ba9296" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/eef488991d53e58e60c9554b09b1201ca5ba9296", + "reference": "eef488991d53e58e60c9554b09b1201ca5ba9296", + "shasum": "" + }, + "require": { + "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "~2.0", + "phpunit/phpunit": "^6.3 || ^7.0 || ^8.0" + }, + "suggest": { + "ext-bcmath": "BCmath is the fallback extension for big integer calculations", + "ext-curl": "For loading OID information from the web if they have not bee defined statically", + "ext-gmp": "GMP is the preferred extension for big integer calculations", + "phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "FG\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Friedrich Große", + "email": "friedrich.grosse@gmail.com", + "homepage": "https://github.com/FGrosse", + "role": "Author" + }, + { + "name": "All contributors", + "homepage": "https://github.com/FGrosse/PHPASN1/contributors" + } + ], + "description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.", + "homepage": "https://github.com/FGrosse/PHPASN1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "ber", + "binary", + "decoding", + "encoding", + "x.509", + "x.690", + "x509", + "x690" + ], + "support": { + "issues": "https://github.com/fgrosse/PHPASN1/issues", + "source": "https://github.com/fgrosse/PHPASN1/tree/v2.4.0" + }, + "time": "2021-12-11T12:41:06+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.6", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "f7948baaa0330277c729714910336383286305da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da", + "reference": "f7948baaa0330277c729714910336383286305da", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.6" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2022-11-02T16:23:29+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.13.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a6232229a8309e8811dc751c28b91cb34b2943e1", + "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.10", + "php-coveralls/php-coveralls": "^2.5.2", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.15", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2022-10-31T19:28:50+00:00" + }, + { + "name": "fruitcake/laravel-cors", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/laravel-cors.git", + "reference": "7c036ec08972d8d5d9db637e772af6887828faf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/7c036ec08972d8d5d9db637e772af6887828faf5", + "reference": "7c036ec08972d8d5d9db637e772af6887828faf5", + "shasum": "" + }, + "require": { + "fruitcake/php-cors": "^1.2", + "illuminate/contracts": "^6|^7|^8|^9", + "illuminate/support": "^6|^7|^8|^9", + "php": "^7.4|^8.0" + }, + "require-dev": { + "laravel/framework": "^6|^7.24|^8", + "orchestra/testbench-dusk": "^4|^5|^6|^7", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Fruitcake\\Cors\\CorsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application", + "keywords": [ + "api", + "cors", + "crossdomain", + "laravel" + ], + "support": { + "issues": "https://github.com/fruitcake/laravel-cors/issues", + "source": "https://github.com/fruitcake/laravel-cors/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-02-23T14:53:22+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-02-20T15:07:15+00:00" + }, + { + "name": "google/recaptcha", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/google/recaptcha.git", + "reference": "614f25a9038be4f3f2da7cbfd778dc5b357d2419" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/google/recaptcha/zipball/614f25a9038be4f3f2da7cbfd778dc5b357d2419", + "reference": "614f25a9038be4f3f2da7cbfd778dc5b357d2419", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.2.20|^2.15", + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^4.8.36|^5.7.27|^6.59|^7.5.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "ReCaptcha\\": "src/ReCaptcha" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Client library for reCAPTCHA, a free service that protects websites from spam and abuse.", + "homepage": "https://www.google.com/recaptcha/", + "keywords": [ + "Abuse", + "captcha", + "recaptcha", + "spam" + ], + "support": { + "forum": "https://groups.google.com/forum/#!forum/recaptcha", + "issues": "https://github.com/google/recaptcha/issues", + "source": "https://github.com/google/recaptcha" + }, + "time": "2020-03-31T17:50:54+00:00" + }, + { + "name": "graham-campbell/analyzer", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Analyzer.git", + "reference": "cfeae1d6d451be116d7d6f2f46b609bbb01063b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Analyzer/zipball/cfeae1d6d451be116d7d6f2f46b609bbb01063b7", + "reference": "cfeae1d6d451be116d7d6f2f46b609bbb01063b7", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.13", + "php": "^7.4.15 || ^8.0.2", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/reflection-docblock": "^5.3", + "phpdocumentor/type-resolver": "^1.6" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "phpunit/phpunit": "Required to use the analysis trait." + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\Analyzer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Checks if referenced classes really exist.", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "analysis", + "analyzer", + "classes", + "testing" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Analyzer/issues", + "source": "https://github.com/GrahamCampbell/Analyzer/tree/v3.1.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/analyzer", + "type": "tidelift" + } + ], + "time": "2022-02-07T10:57:51+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:56:11+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "67c26b443f348a51926030c83481b85718457d3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", + "reference": "67c26b443f348a51926030c83481b85718457d3d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.4.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2022-10-26T14:07:24+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "http-interop/http-factory-guzzle", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/http-interop/http-factory-guzzle.git", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/8f06e92b95405216b237521cc64c804dd44c4a81", + "reference": "8f06e92b95405216b237521cc64c804dd44c4a81", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7||^2.0", + "php": ">=7.3", + "psr/http-factory": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "guzzlehttp/psr7": "Includes an HTTP factory starting in version 2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Factory\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "An HTTP Factory using Guzzle PSR7", + "keywords": [ + "factory", + "http", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/http-interop/http-factory-guzzle/issues", + "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.0" + }, + "time": "2021-07-21T13:50:14+00:00" + }, + { + "name": "huddledigital/zendesk-laravel", + "version": "v3.7", + "source": { + "type": "git", + "url": "https://github.com/huddledigital/zendesk-laravel.git", + "reference": "068605b427111af4c5516ec9c3b3cc5a370efd0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/huddledigital/zendesk-laravel/zipball/068605b427111af4c5516ec9c3b3cc5a370efd0d", + "reference": "068605b427111af4c5516ec9c3b3cc5a370efd0d", + "shasum": "" + }, + "require": { + "illuminate/support": "~5.4|^6.0|^7.0|^8.0|^9.0", + "php": ">=5.4.0", + "zendesk/zendesk_api_client_php": "2.*" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Huddle\\Zendesk\\Providers\\ZendeskServiceProvider" + ], + "aliases": { + "Zendesk": "Huddle\\Zendesk\\Facades\\Zendesk" + } + } + }, + "autoload": { + "psr-4": { + "Huddle\\Zendesk\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Huddle Digital Ltd", + "email": "info@workwithhuddle.com" + } + ], + "description": "Laravel wrapper for zendesk/zendesk_api_client_php package", + "homepage": "http://workwithhuddle.com", + "keywords": [ + "Zendesk" + ], + "support": { + "issues": "https://github.com/huddledigital/zendesk-laravel/issues", + "source": "https://github.com/huddledigital/zendesk-laravel/tree/v3.7" + }, + "time": "2022-02-07T12:03:38+00:00" + }, + { + "name": "intervention/image", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "04be355f8d6734c826045d02a1079ad658322dad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad", + "reference": "04be355f8d6734c826045d02a1079ad658322dad", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "guzzlehttp/psr7": "~1.1 || ^2.0", + "php": ">=5.4.0" + }, + "require-dev": { + "mockery/mockery": "~0.9.2", + "phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15" + }, + "suggest": { + "ext-gd": "to use GD library based image processing.", + "ext-imagick": "to use Imagick based image processing.", + "intervention/imagecache": "Caching extension for the Intervention Image library" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + }, + "laravel": { + "providers": [ + "Intervention\\Image\\ImageServiceProvider" + ], + "aliases": { + "Image": "Intervention\\Image\\Facades\\Image" + } + } + }, + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src/Intervention/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Image handling and manipulation library with support for Laravel integration", + "homepage": "http://image.intervention.io/", + "keywords": [ + "gd", + "image", + "imagick", + "laravel", + "thumbnail", + "watermark" + ], + "support": { + "issues": "https://github.com/Intervention/image/issues", + "source": "https://github.com/Intervention/image/tree/2.7.2" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + } + ], + "time": "2022-05-21T17:30:32+00:00" + }, + { + "name": "jamesmills/laravel-timezone", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/jamesmills/laravel-timezone.git", + "reference": "40df97b57e546200ded36020bfe6ad88528aaa4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jamesmills/laravel-timezone/zipball/40df97b57e546200ded36020bfe6ad88528aaa4a", + "reference": "40df97b57e546200ded36020bfe6ad88528aaa4a", + "shasum": "" + }, + "require": { + "laravel/framework": "5.6.* || 5.7.* || 5.8.* || ^6 || ^7 || ^8 || ^9", + "nesbot/carbon": "^1.0 || ^2.0", + "php": ">=7.4", + "torann/geoip": "^3.0", + "treeware/plant": "dev-main" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.12" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "JamesMills\\LaravelTimezone\\LaravelTimezoneServiceProvider" + ] + }, + "treeware": { + "teaser": [ + "Your message to the consumers of your package to convince them.", + "Multiple lines are possible, but not more than 3 lines and 200 characters." + ], + "priceGroups": { + "useful": 100, + "important": 250, + "critical": 500 + } + } + }, + "autoload": { + "psr-4": { + "JamesMills\\LaravelTimezone\\": "src/", + "JamesMills\\LaravelTimezone\\Database\\Seeds\\": "database/seeds/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Mills", + "email": "james@clicksco.com" + } + ], + "description": "Timezone storage and retrieval for Laravel", + "keywords": [ + "laravel", + "timezone" + ], + "support": { + "issues": "https://github.com/jamesmills/laravel-timezone/issues", + "source": "https://github.com/jamesmills/laravel-timezone/tree/1.11.0" + }, + "time": "2022-02-16T04:54:03+00:00" + }, + { + "name": "jasonmccreary/laravel-test-assertions", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/jasonmccreary/laravel-test-assertions.git", + "reference": "2547c0366f1ee9a2d58b031468b26edc63faef4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jasonmccreary/laravel-test-assertions/zipball/2547c0366f1ee9a2d58b031468b26edc63faef4e", + "reference": "2547c0366f1ee9a2d58b031468b26edc63faef4e", + "shasum": "" + }, + "require": { + "illuminate/testing": "^8.0|^9.0", + "mockery/mockery": "^1.4.2", + "php": ">=7.3|^8.0", + "phpunit/phpunit": "^9.3.3" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "JMac\\Testing\\AdditionalAssertionsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "JMac\\Testing\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jason McCreary", + "email": "jason@pureconcepts.net" + } + ], + "description": "A set of helpful assertions when testing Laravel applications.", + "support": { + "issues": "https://github.com/jasonmccreary/laravel-test-assertions/issues", + "source": "https://github.com/jasonmccreary/laravel-test-assertions/tree/v2.1.1" + }, + "time": "2022-03-08T14:47:39+00:00" + }, + { + "name": "jaybizzle/crawler-detect", + "version": "v1.2.112", + "source": { + "type": "git", + "url": "https://github.com/JayBizzle/Crawler-Detect.git", + "reference": "2c555ce35a07a5c1c808cee7d5bb52c41a4c7b2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JayBizzle/Crawler-Detect/zipball/2c555ce35a07a5c1c808cee7d5bb52c41a4c7b2f", + "reference": "2c555ce35a07a5c1c808cee7d5bb52c41a4c7b2f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.5|^6.5|^9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Jaybizzle\\CrawlerDetect\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Beech", + "email": "m@rkbee.ch", + "role": "Developer" + } + ], + "description": "CrawlerDetect is a PHP class for detecting bots/crawlers/spiders via the user agent", + "homepage": "https://github.com/JayBizzle/Crawler-Detect/", + "keywords": [ + "crawler", + "crawler detect", + "crawler detector", + "crawlerdetect", + "php crawler detect" + ], + "support": { + "issues": "https://github.com/JayBizzle/Crawler-Detect/issues", + "source": "https://github.com/JayBizzle/Crawler-Detect/tree/v1.2.112" + }, + "time": "2022-10-05T21:52:44+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "reference": "ae547e455a3d8babd07b96966b17d7fd21d9c6af", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.17", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^0.12.66", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.5" + }, + "time": "2021-10-08T21:21:46+00:00" + }, + { + "name": "jenssegers/agent", + "version": "v2.6.4", + "source": { + "type": "git", + "url": "https://github.com/jenssegers/agent.git", + "reference": "daa11c43729510b3700bc34d414664966b03bffe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jenssegers/agent/zipball/daa11c43729510b3700bc34d414664966b03bffe", + "reference": "daa11c43729510b3700bc34d414664966b03bffe", + "shasum": "" + }, + "require": { + "jaybizzle/crawler-detect": "^1.2", + "mobiledetect/mobiledetectlib": "^2.7.6", + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5.0|^6.0|^7.0" + }, + "suggest": { + "illuminate/support": "Required for laravel service providers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + }, + "laravel": { + "providers": [ + "Jenssegers\\Agent\\AgentServiceProvider" + ], + "aliases": { + "Agent": "Jenssegers\\Agent\\Facades\\Agent" + } + } + }, + "autoload": { + "psr-4": { + "Jenssegers\\Agent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jens Segers", + "homepage": "https://jenssegers.com" + } + ], + "description": "Desktop/mobile user agent parser with support for Laravel, based on Mobiledetect", + "homepage": "https://github.com/jenssegers/agent", + "keywords": [ + "Agent", + "browser", + "desktop", + "laravel", + "mobile", + "platform", + "user agent", + "useragent" + ], + "support": { + "issues": "https://github.com/jenssegers/agent/issues", + "source": "https://github.com/jenssegers/agent/tree/v2.6.4" + }, + "funding": [ + { + "url": "https://github.com/jenssegers", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/jenssegers/agent", + "type": "tidelift" + } + ], + "time": "2020-06-13T08:05:20+00:00" + }, + { + "name": "jenssegers/optimus", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/jenssegers/optimus.git", + "reference": "a062ac06598e72a25a17ea6cba87f9e02d07b1bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jenssegers/optimus/zipball/a062ac06598e72a25a17ea6cba87f9e02d07b1bc", + "reference": "a062ac06598e72a25a17ea6cba87f9e02d07b1bc", + "shasum": "" + }, + "require": { + "php": "^7.4||^8.0", + "phpseclib/phpseclib": "^3.0", + "symfony/console": "^5.0||^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.10" + }, + "suggest": { + "ext-gmp": "Required for 32bit systems" + }, + "bin": [ + "bin/optimus" + ], + "type": "library", + "autoload": { + "psr-4": { + "Jenssegers\\Optimus\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jens Segers", + "homepage": "https://jenssegers.com" + } + ], + "description": "Id obfuscation based on Knuth's integer hash method", + "homepage": "https://github.com/jenssegers/optimus", + "keywords": [ + "hashids", + "id obfuscation", + "ids", + "obfuscation", + "optimus" + ], + "support": { + "issues": "https://github.com/jenssegers/optimus/issues", + "source": "https://github.com/jenssegers/optimus/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/jenssegers", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/jenssegers/optimus", + "type": "tidelift" + } + ], + "time": "2021-12-21T16:15:54+00:00" + }, + { + "name": "johnkary/phpunit-speedtrap", + "version": "v4.0.1", + "source": { + "type": "git", + "url": "https://github.com/johnkary/phpunit-speedtrap.git", + "reference": "d6600d2218396b78856c335f83479503957a5fa9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/johnkary/phpunit-speedtrap/zipball/d6600d2218396b78856c335f83479503957a5fa9", + "reference": "d6600d2218396b78856c335f83479503957a5fa9", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "JohnKary\\PHPUnit\\Listener\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Kary", + "email": "john@johnkary.net" + } + ], + "description": "Find and report on slow tests in your PHPUnit test suite", + "homepage": "https://github.com/johnkary/phpunit-speedtrap", + "keywords": [ + "phpunit", + "profile", + "slow" + ], + "support": { + "issues": "https://github.com/johnkary/phpunit-speedtrap/issues", + "source": "https://github.com/johnkary/phpunit-speedtrap/tree/v4.0.1" + }, + "time": "2022-10-17T00:56:56+00:00" + }, + { + "name": "laravel/fortify", + "version": "v1.13.7", + "source": { + "type": "git", + "url": "https://github.com/laravel/fortify.git", + "reference": "28c2dc66639571ac656c13617a1a0876a82319b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/fortify/zipball/28c2dc66639571ac656c13617a1a0876a82319b1", + "reference": "28c2dc66639571ac656c13617a1a0876a82319b1", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "ext-json": "*", + "illuminate/support": "^8.82|^9.0", + "php": "^7.3|^8.0", + "pragmarx/google2fa": "^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Fortify\\FortifyServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Fortify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Backend controllers and scaffolding for Laravel authentication.", + "keywords": [ + "auth", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/fortify/issues", + "source": "https://github.com/laravel/fortify" + }, + "time": "2022-11-04T20:57:17+00:00" + }, + { + "name": "laravel/framework", + "version": "v9.41.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "cc902ce61b4ca08ca7449664cfab2fa96a1d1e28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/cc902ce61b4ca08ca7449664cfab2fa96a1d1e28", + "reference": "cc902ce61b4ca08ca7449664cfab2fa96a1d1e28", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "dragonmantank/cron-expression": "^3.3.2", + "egulias/email-validator": "^3.2.1", + "ext-mbstring": "*", + "ext-openssl": "*", + "fruitcake/php-cors": "^1.2", + "laravel/serializable-closure": "^1.2.2", + "league/commonmark": "^2.2", + "league/flysystem": "^3.8.0", + "monolog/monolog": "^2.0", + "nesbot/carbon": "^2.62.1", + "nunomaduro/termwind": "^1.13", + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.2.2", + "symfony/console": "^6.0.9", + "symfony/error-handler": "^6.0", + "symfony/finder": "^6.0", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/mailer": "^6.0", + "symfony/mime": "^6.0", + "symfony/process": "^6.0", + "symfony/routing": "^6.0", + "symfony/uid": "^6.0", + "symfony/var-dumper": "^6.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.235.5", + "doctrine/dbal": "^2.13.3|^3.1.4", + "fakerphp/faker": "^1.9.2", + "guzzlehttp/guzzle": "^7.5", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^7.11", + "pda/pheanstalk": "^4.0", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^9.5.8", + "predis/predis": "^1.1.9|^2.0.2", + "symfony/cache": "^6.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", + "ext-bcmath": "Required to use the multiple_of validation rule.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.5).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.5.1).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8).", + "predis/predis": "Required to use the predis connector (^1.1.9|^2.0.2).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-11-22T15:10:46+00:00" + }, + { + "name": "laravel/horizon", + "version": "v5.10.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/horizon.git", + "reference": "07a5d73b804c6ba17598e378057f4353c983fb3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/horizon/zipball/07a5d73b804c6ba17598e378057f4353c983fb3a", + "reference": "07a5d73b804c6ba17598e378057f4353c983fb3a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcntl": "*", + "ext-posix": "*", + "illuminate/contracts": "^8.17|^9.0", + "illuminate/queue": "^8.17|^9.0", + "illuminate/support": "^8.17|^9.0", + "nesbot/carbon": "^2.17", + "php": "^7.3|^8.0", + "ramsey/uuid": "^4.0", + "symfony/error-handler": "^5.0|^6.0", + "symfony/process": "^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^6.0|^7.0", + "phpunit/phpunit": "^9.0", + "predis/predis": "^1.1|^2.0" + }, + "suggest": { + "ext-redis": "Required to use the Redis PHP driver.", + "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Horizon\\HorizonServiceProvider" + ], + "aliases": { + "Horizon": "Laravel\\Horizon\\Horizon" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Horizon\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Dashboard and code-driven configuration for Laravel queues.", + "keywords": [ + "laravel", + "queue" + ], + "support": { + "issues": "https://github.com/laravel/horizon/issues", + "source": "https://github.com/laravel/horizon/tree/v5.10.4" + }, + "time": "2022-11-07T08:57:31+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/47afb7fae28ed29057fdca37e16a84f90cc62fae", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-09-08T13:45:54+00:00" + }, + { + "name": "laravel/telescope", + "version": "v4.9.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "017eaf1b6d19392d196adcb4151bdf6d59612d66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/017eaf1b6d19392d196adcb4151bdf6d59612d66", + "reference": "017eaf1b6d19392d196adcb4151bdf6d59612d66", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0", + "php": "^7.3|^8.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "orchestra/testbench": "^6.0|^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v4.9.6" + }, + "time": "2022-11-08T07:00:35+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "5062061b4924af3392225dd482ca7b4d85d8b8ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/5062061b4924af3392225dd482ca7b4d85d8b8ef", + "reference": "5062061b4924af3392225dd482ca7b4d85d8b8ef", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.10.4|^0.11.1", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.7.3" + }, + "time": "2022-11-09T15:11:38+00:00" + }, + { + "name": "lastguest/murmurhash", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/lastguest/murmurhash-php.git", + "reference": "4fb7516f67e695e5d7fa129d1bbb925ec0ebe408" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lastguest/murmurhash-php/zipball/4fb7516f67e695e5d7fa129d1bbb925ec0ebe408", + "reference": "4fb7516f67e695e5d7fa129d1bbb925ec0ebe408", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpstan/phpstan": "^0.6.3", + "phpunit/phpunit": "^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "lastguest\\": "src/lastguest/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stefano Azzolini", + "email": "lastguest@gmail.com", + "homepage": "https://github.com/lastguest/murmurhash-php" + } + ], + "description": "MurmurHash3 Hash", + "homepage": "https://github.com/lastguest/murmurhash-php", + "keywords": [ + "hash", + "hashing", + "murmur" + ], + "support": { + "issues": "https://github.com/lastguest/murmurhash-php/issues", + "source": "https://github.com/lastguest/murmurhash-php/tree/master" + }, + "time": "2017-10-10T15:16:12+00:00" + }, + { + "name": "league/commonmark", + "version": "2.3.7", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "a36bd2be4f5387c0f3a8792a0d76b7d68865abbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/a36bd2be4f5387c0f3a8792a0d76b7d68865abbf", + "reference": "a36bd2be4f5387c0f3a8792a0d76b7d68865abbf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2022-11-03T17:29:46+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" + }, + { + "name": "league/flysystem", + "version": "3.10.4", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "a7790f3dd1b27af81d380e6b2afa77c16ab7e181" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a7790f3dd1b27af81d380e6b2afa77c16ab7e181", + "reference": "a7790f3dd1b27af81d380e6b2afa77c16ab7e181", + "shasum": "" + }, + "require": { + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.1", + "aws/aws-sdk-php": "^3.198.1", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^3.0.14", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^9.5.11", + "sabre/dav": "^4.3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.10.4" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-11-26T19:48:01+00:00" + }, + { + "name": "league/glide", + "version": "2.2.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/glide.git", + "reference": "bff5b0fe2fd26b2fde2d6958715fde313887d79d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/glide/zipball/bff5b0fe2fd26b2fde2d6958715fde313887d79d", + "reference": "bff5b0fe2fd26b2fde2d6958715fde313887d79d", + "shasum": "" + }, + "require": { + "intervention/image": "^2.7", + "league/flysystem": "^2.0|^3.0", + "php": "^7.2|^8.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "phpunit/php-token-stream": "^3.1|^4.0", + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Glide\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Reinink", + "email": "jonathan@reinink.ca", + "homepage": "http://reinink.ca" + }, + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com", + "homepage": "https://titouangalopin.com" + } + ], + "description": "Wonderfully easy on-demand image manipulation library with an HTTP based API.", + "homepage": "http://glide.thephpleague.com", + "keywords": [ + "ImageMagick", + "editing", + "gd", + "image", + "imagick", + "league", + "manipulation", + "processing" + ], + "support": { + "issues": "https://github.com/thephpleague/glide/issues", + "source": "https://github.com/thephpleague/glide/tree/2.2.2" + }, + "time": "2022-02-21T07:40:55+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-04-17T13:12:02+00:00" + }, + { + "name": "livewire/livewire", + "version": "v2.10.7", + "source": { + "type": "git", + "url": "https://github.com/livewire/livewire.git", + "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/livewire/zipball/fa0441bf82f1674beecb3a8ad8a4ae428736ed18", + "reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18", + "shasum": "" + }, + "require": { + "illuminate/database": "^7.0|^8.0|^9.0", + "illuminate/support": "^7.0|^8.0|^9.0", + "illuminate/validation": "^7.0|^8.0|^9.0", + "league/mime-type-detection": "^1.9", + "php": "^7.2.5|^8.0", + "symfony/http-kernel": "^5.0|^6.0" + }, + "require-dev": { + "calebporzio/sushi": "^2.1", + "laravel/framework": "^7.0|^8.0|^9.0", + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "^5.0|^6.0|^7.0", + "orchestra/testbench-dusk": "^5.2|^6.0|^7.0", + "phpunit/phpunit": "^8.4|^9.0", + "psy/psysh": "@stable" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\LivewireServiceProvider" + ], + "aliases": { + "Livewire": "Livewire\\Livewire" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "A front-end framework for Laravel.", + "support": { + "issues": "https://github.com/livewire/livewire/issues", + "source": "https://github.com/livewire/livewire/tree/v2.10.7" + }, + "funding": [ + { + "url": "https://github.com/livewire", + "type": "github" + } + ], + "time": "2022-08-08T13:52:53+00:00" + }, + { + "name": "maennchen/zipstream-php", + "version": "2.2.6", + "source": { + "type": "git", + "url": "https://github.com/maennchen/ZipStream-PHP.git", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "shasum": "" + }, + "require": { + "myclabs/php-enum": "^1.5", + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.9", + "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", + "mikey179/vfsstream": "^1.6", + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpunit": "^8.5.8 || ^9.4.2", + "vimeo/psalm": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZipStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paul Duncan", + "email": "pabs@pablotron.org" + }, + { + "name": "Jonatan Männchen", + "email": "jonatan@maennchen.ch" + }, + { + "name": "Jesse Donat", + "email": "donatj@gmail.com" + }, + { + "name": "András Kolesár", + "email": "kolesar@kolesar.hu" + } + ], + "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", + "keywords": [ + "stream", + "zip" + ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.6" + }, + "funding": [ + { + "url": "https://github.com/maennchen", + "type": "github" + }, + { + "url": "https://opencollective.com/zipstream", + "type": "open_collective" + } + ], + "time": "2022-11-25T18:57:19+00:00" + }, + { + "name": "mdanter/ecc", + "version": "v0.5.2", + "source": { + "type": "git", + "url": "https://github.com/phpecc/phpecc.git", + "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpecc/phpecc/zipball/b95f25cc1bacc83a9f0ccd375900b7cfd343029e", + "reference": "b95f25cc1bacc83a9f0ccd375900b7cfd343029e", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "fgrosse/phpasn1": "^2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0", + "squizlabs/php_codesniffer": "^2.0", + "symfony/yaml": "^2.6|^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mdanter\\Ecc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matyas Danter", + "homepage": "http://matejdanter.com/", + "role": "Author" + }, + { + "name": "Thibaud Fabre", + "email": "thibaud@aztech.io", + "homepage": "http://aztech.io", + "role": "Maintainer" + }, + { + "name": "Thomas Kerin", + "email": "afk11@users.noreply.github.com", + "role": "Maintainer" + } + ], + "description": "PHP Elliptic Curve Cryptography library", + "homepage": "https://github.com/phpecc/phpecc", + "keywords": [ + "Diffie", + "ECDSA", + "Hellman", + "curve", + "ecdh", + "elliptic", + "nistp192", + "nistp224", + "nistp256", + "nistp384", + "nistp521", + "phpecc", + "secp256k1", + "secp256r1" + ], + "support": { + "issues": "https://github.com/phpecc/phpecc/issues", + "source": "https://github.com/phpecc/phpecc/tree/master" + }, + "time": "2018-12-03T18:17:01+00:00" + }, + { + "name": "mmucklo/inflect", + "version": "v0.3.0", + "source": { + "type": "git", + "url": "https://github.com/mmucklo/inflect.git", + "reference": "b665bcd3d4c23b6aa1990b6405ff96dd437689e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mmucklo/inflect/zipball/b665bcd3d4c23b6aa1990b6405ff96dd437689e9", + "reference": "b665bcd3d4c23b6aa1990b6405ff96dd437689e9", + "shasum": "" + }, + "require": { + "php": ">=5.3.17" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Inflect": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sho Kuwamoto", + "email": "sho@kuwamoto.org" + }, + { + "name": "Matthew J. Mucklo", + "email": "mmucklo@gmail.com" + } + ], + "description": "inflect - a memoizing inflector for php", + "keywords": [ + "inflect", + "inflector", + "pluralize", + "singularize", + "urlify" + ], + "support": { + "issues": "https://github.com/mmucklo/inflect/issues", + "source": "https://github.com/mmucklo/inflect/tree/v0.3.0" + }, + "time": "2015-05-16T04:16:08+00:00" + }, + { + "name": "mobiledetect/mobiledetectlib", + "version": "2.8.41", + "source": { + "type": "git", + "url": "https://github.com/serbanghita/Mobile-Detect.git", + "reference": "fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1", + "reference": "fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1", + "shasum": "" + }, + "require": { + "php": ">=5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35||~5.7" + }, + "type": "library", + "autoload": { + "psr-0": { + "Detection": "namespaced/" + }, + "classmap": [ + "Mobile_Detect.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "http://mobiledetect.net", + "role": "Developer" + } + ], + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "keywords": [ + "detect mobile devices", + "mobile", + "mobile detect", + "mobile detector", + "php mobile detect" + ], + "support": { + "issues": "https://github.com/serbanghita/Mobile-Detect/issues", + "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.41" + }, + "time": "2022-11-08T18:31:26+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "reference": "e92dcc83d5a51851baf5f5591d32cb2b16e3684e", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.5.1" + }, + "time": "2022-09-07T15:32:08+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", + "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-07-24T11:55:47+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1" + }, + "time": "2021-06-14T00:11:39+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "myclabs/php-enum", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.4" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2022-08-04T09:53:51+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.63.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "ad35dd71a6a212b98e4b87e97389b6fa85f0e347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/ad35dd71a6a212b98e4b87e97389b6fa85f0e347", + "reference": "ad35dd71a6a212b98e4b87e97389b6fa85f0e347", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2022-10-30T18:34:28+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.3" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.3" + }, + "time": "2022-10-13T01:24:26+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.8", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.3" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.8" + }, + "time": "2022-09-12T23:36:20+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + }, + "time": "2022-11-12T15:38:23+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v6.3.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "0f6349c3ed5dd28467087b08fb59384bb458a22b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/0f6349c3ed5dd28467087b08fb59384bb458a22b", + "reference": "0f6349c3ed5dd28467087b08fb59384bb458a22b", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.14.5", + "php": "^8.0.0", + "symfony/console": "^6.0.2" + }, + "require-dev": { + "brianium/paratest": "^6.4.1", + "laravel/framework": "^9.26.1", + "laravel/pint": "^1.1.1", + "nunomaduro/larastan": "^1.0.3", + "nunomaduro/mock-final-classes": "^1.1.0", + "orchestra/testbench": "^7.7", + "phpunit/phpunit": "^9.5.23", + "spatie/ignition": "^1.4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "6.x-dev" + }, + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-09-29T12:29:49+00:00" + }, + { + "name": "nunomaduro/larastan", + "version": "2.2.9", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/larastan.git", + "reference": "333e7915b984ce6606175749430081a372ead37e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/333e7915b984ce6606175749430081a372ead37e", + "reference": "333e7915b984ce6606175749430081a372ead37e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^9", + "illuminate/container": "^9", + "illuminate/contracts": "^9", + "illuminate/database": "^9", + "illuminate/http": "^9", + "illuminate/pipeline": "^9", + "illuminate/support": "^9", + "mockery/mockery": "^1.4.4", + "php": "^8.0.2", + "phpmyadmin/sql-parser": "^5.5", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13.2", + "orchestra/testbench": "^7.0.0", + "phpunit/phpunit": "^9.5.11" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/nunomaduro/larastan/issues", + "source": "https://github.com/nunomaduro/larastan/tree/2.2.9" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/canvural", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-11-04T14:58:00+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v1.14.2", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "9a8218511eb1a0965629ff820dda25985440aefc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/9a8218511eb1a0965629ff820dda25985440aefc", + "reference": "9a8218511eb1a0965629ff820dda25985440aefc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0", + "symfony/console": "^5.3.0|^6.0.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "laravel/pint": "^1.0.0", + "pestphp/pest": "^1.21.0", + "pestphp/pest-plugin-mock": "^1.0", + "phpstan/phpstan": "^1.4.6", + "phpstan/phpstan-strict-rules": "^1.1.0", + "symfony/var-dumper": "^5.2.7|^6.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.14.2" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2022-10-28T22:51:32+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "f734364e38a876a23be4d906a2a089e1315be18a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/f734364e38a876a23be4d906a2a089e1315be18a", + "reference": "f734364e38a876a23be4d906a2a089e1315be18a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "php-http/message-factory": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || 8.5 || 9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.5.1" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2022-06-22T07:13:36+00:00" + }, + { + "name": "orchestra/testbench", + "version": "v7.14.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench.git", + "reference": "717d97c9f8d256371c46659af2754f51accbfdce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/717d97c9f8d256371c46659af2754f51accbfdce", + "reference": "717d97c9f8d256371c46659af2754f51accbfdce", + "shasum": "" + }, + "require": { + "fakerphp/faker": "^1.9.2", + "laravel/framework": "^9.36", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^7.14", + "php": "^8.0", + "phpunit/phpunit": "^9.5.10", + "spatie/laravel-ray": "^1.28", + "symfony/process": "^6.0.9", + "symfony/yaml": "^6.0.9", + "vlucas/phpdotenv": "^5.4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Laravel Testing Helper for Packages Development", + "homepage": "https://packages.tools/testbench/", + "keywords": [ + "BDD", + "TDD", + "laravel", + "orchestra-platform", + "orchestral", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench/tree/v7.14.0" + }, + "funding": [ + { + "url": "https://paypal.me/crynobone", + "type": "custom" + }, + { + "url": "https://liberapay.com/crynobone", + "type": "liberapay" + } + ], + "time": "2022-11-22T22:19:11+00:00" + }, + { + "name": "orchestra/testbench-core", + "version": "v7.14.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench-core.git", + "reference": "fb8c90c5f5cb9033e085e4fbf581093cd6e32862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/fb8c90c5f5cb9033e085e4fbf581093cd6e32862", + "reference": "fb8c90c5f5cb9033e085e4fbf581093cd6e32862", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "fakerphp/faker": "^1.9.2", + "laravel/framework": "^9.36", + "laravel/laravel": "9.x-dev", + "laravel/pint": "^1.1", + "mockery/mockery": "^1.5.1", + "orchestra/canvas": "^7.0", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9.5.10", + "spatie/laravel-ray": "^1.28", + "symfony/process": "^6.0.9", + "symfony/yaml": "^6.0.9", + "vlucas/phpdotenv": "^5.4.1" + }, + "suggest": { + "brianium/paratest": "Allow using parallel tresting (^6.4).", + "fakerphp/faker": "Allow using Faker for testing (^1.9.2).", + "laravel/framework": "Required for testing (^9.34).", + "mockery/mockery": "Allow using Mockery for testing (^1.5.1).", + "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.2).", + "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^7.0).", + "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^7.0).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^9.5.10).", + "symfony/yaml": "Required for CLI Commander (^6.0.9).", + "vlucas/phpdotenv": "Required for CLI Commander (^5.4.1)." + }, + "bin": [ + "testbench" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Orchestra\\Testbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Testing Helper for Laravel Development", + "homepage": "https://packages.tools/testbench", + "keywords": [ + "BDD", + "TDD", + "laravel", + "orchestra-platform", + "orchestral", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench-core" + }, + "funding": [ + { + "url": "https://paypal.me/crynobone", + "type": "custom" + }, + { + "url": "https://liberapay.com/crynobone", + "type": "liberapay" + } + ], + "time": "2022-11-22T09:06:48+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "pestphp/pest", + "version": "v1.22.2", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "339414e34842f9463f33641b00559d4bf227e478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/339414e34842f9463f33641b00559d4bf227e478", + "reference": "339414e34842f9463f33641b00559d4bf227e478", + "shasum": "" + }, + "require": { + "nunomaduro/collision": "^5.11.0|^6.3.0", + "pestphp/pest-plugin": "^1.1.0", + "php": "^7.3 || ^8.0", + "phpunit/phpunit": "^9.5.26" + }, + "require-dev": { + "illuminate/console": "^8.83.26", + "illuminate/support": "^8.83.26", + "laravel/dusk": "^6.25.2", + "pestphp/pest-dev-tools": "^1.0.0", + "pestphp/pest-plugin-parallel": "^1.2" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + }, + "pest": { + "plugins": [ + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Environment" + ] + }, + "laravel": { + "providers": [ + "Pest\\Laravel\\PestServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v1.22.2" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/lukeraymonddowning", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/olivernybroe", + "type": "github" + }, + { + "url": "https://github.com/owenvoke", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-11-09T21:10:57+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "606c5f79c6a339b49838ffbee0151ca519efe378" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/606c5f79c6a339b49838ffbee0151ca519efe378", + "reference": "606c5f79c6a339b49838ffbee0151ca519efe378", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "pestphp/pest": "<1.0" + }, + "require-dev": { + "composer/composer": "^2.4.2", + "pestphp/pest": "^1.22.1", + "pestphp/pest-dev-tools": "^1.0.0" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v1.1.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-09-18T13:18:17+00:00" + }, + { + "name": "pestphp/pest-plugin-faker", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-faker.git", + "reference": "9d93419f1f47ffd856ee544317b2f9144a129044" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-faker/zipball/9d93419f1f47ffd856ee544317b2f9144a129044", + "reference": "9d93419f1f47ffd856ee544317b2f9144a129044", + "shasum": "" + }, + "require": { + "fakerphp/faker": "^1.9.1", + "pestphp/pest": "^1.0", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "pestphp/pest-dev-tools": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/Faker.php" + ], + "psr-4": { + "Pest\\Faker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Faker Plugin", + "keywords": [ + "faker", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-faker/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2021-01-03T15:42:35+00:00" + }, + { + "name": "pestphp/pest-plugin-laravel", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-laravel.git", + "reference": "561930875e0336441f93fbd120fd53a2a890a8f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/561930875e0336441f93fbd120fd53a2a890a8f5", + "reference": "561930875e0336441f93fbd120fd53a2a890a8f5", + "shasum": "" + }, + "require": { + "laravel/framework": "^7.30.6 || ^8.83.23 || ^9.30.1", + "pestphp/pest": "^1.22.1", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "orchestra/testbench": "^5.20.0 || ^6.25.0 || ^7.7.0", + "pestphp/pest-dev-tools": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Laravel Plugin", + "keywords": [ + "framework", + "laravel", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-09-18T13:04:53+00:00" + }, + { + "name": "pestphp/pest-plugin-livewire", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-livewire.git", + "reference": "30e259e57c18dd40402e7fd29d46344a6cb9ff03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-livewire/zipball/30e259e57c18dd40402e7fd29d46344a6cb9ff03", + "reference": "30e259e57c18dd40402e7fd29d46344a6cb9ff03", + "shasum": "" + }, + "require": { + "livewire/livewire": "^1.2|^2.0", + "pestphp/pest": "^1.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^6.4", + "pestphp/pest-dev-tools": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Livewire Plugin", + "keywords": [ + "framework", + "livewire", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-livewire/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2021-01-03T15:37:46+00:00" + }, + { + "name": "pestphp/pest-plugin-parallel", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-parallel.git", + "reference": "7ae93d4052d2f45c0a37ca34f5dea940fb28cf31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-parallel/zipball/7ae93d4052d2f45c0a37ca34f5dea940fb28cf31", + "reference": "7ae93d4052d2f45c0a37ca34f5dea940fb28cf31", + "shasum": "" + }, + "require": { + "brianium/paratest": "^6.4.2", + "pestphp/pest-plugin": "^1.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "laravel/framework": "<8.55", + "nunomaduro/collision": "<5.8", + "pestphp/pest": "<1.16" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.0", + "pestphp/pest": "1.x-dev", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-strict-rules": "^1.3", + "symfony/var-dumper": "^5.0 || ^6.0", + "thecodingmachine/phpstan-strict-rules": "^1.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Parallel\\Plugin" + ] + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/Autoload.php", + "build/RunnerWorker.php", + "build/BaseRunner.php" + ], + "psr-4": { + "Pest\\Parallel\\": "src/" + }, + "exclude-from-classmap": [ + "ParaTest\\Runners\\PHPUnit\\Worker\\RunnerWorker", + "ParaTest\\Runners\\PHPUnit\\BaseRunner" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Parallel Plugin", + "keywords": [ + "framework", + "parallel", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-parallel/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/lukeraymonddowning", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/octoper", + "type": "github" + }, + { + "url": "https://github.com/olivernybroe", + "type": "github" + }, + { + "url": "https://github.com/owenvoke", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-07-06T08:38:19+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/45db684cd4e186dcdc2b9c06b22970fe123796c0", + "reference": "45db684cd4e186dcdc2b9c06b22970fe123796c0", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "phpspec/prophecy": "^1.10.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "support": { + "issues": "https://github.com/php-http/client-common/issues", + "source": "https://github.com/php-http/client-common/tree/2.6.0" + }, + "time": "2022-09-29T09:59:43+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.14.3", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/31d8ee46d0215108df16a8527c7438e96a4d7735", + "reference": "31d8ee46d0215108df16a8527c7438e96a4d7735", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "require-dev": { + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.14.3" + }, + "time": "2022-07-11T14:04:40+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "f640739f80dfa1152533976e3c112477f69274eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/f640739f80dfa1152533976e3c112477f69274eb", + "reference": "f640739f80dfa1152533976e3c112477f69274eb", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1", + "phpspec/phpspec": "^5.1 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.3.0" + }, + "time": "2022-02-21T09:52:22+00:00" + }, + { + "name": "php-http/message", + "version": "1.13.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/7886e647a30a966a1a8d1dad1845b71ca8678361", + "reference": "7886e647a30a966a1a8d1dad1845b71ca8678361", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.5", + "php": "^7.1 || ^8.0", + "php-http/message-factory": "^1.0.2", + "psr/http-message": "^1.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.6", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0", + "laminas/laminas-diactoros": "^2.0", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "slim/slim": "^3.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "laminas/laminas-diactoros": "Used with Diactoros Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/1.13.0" + }, + "time": "2022-02-11T13:41:14+00:00" + }, + { + "name": "php-http/message-factory", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, + "time": "2015-12-19T14:08:53+00:00" + }, + { + "name": "php-http/promise", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.1.0" + }, + "time": "2020-07-07T09:29:14+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.5.0", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "reference": "8ab99cd0007d880f49f5aa1807033dbfa21b1cb5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "symfony/polyfill-mbstring": "^1.3" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "^3.0" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "sql" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "time": "2021-12-09T04:31:52+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^8.5.28 || ^9.5.21" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2022-07-30T15:51:26+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.17", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/dbc2307d5c69aeb22db136c52e91130d7f2ca761", + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.17" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2022-10-24T10:51:50+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f06dbb052ddc394e7896fcd1cfcd533f9f6ace40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f06dbb052ddc394e7896fcd1cfcd533f9f6ace40", + "reference": "f06dbb052ddc394e7896fcd1cfcd533f9f6ace40", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.8.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.2.0" + }, + "time": "2022-10-17T12:59:16+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d6fdf01c53978b6429f1393ba4afeca39cc68afa", + "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-11-10T09:56:11+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682", + "reference": "e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "phpstan/phpstan": "^1.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.0.0" + }, + "time": "2021-09-23T11:02:21+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "1.4.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6", + "reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.8.6" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.4.4" + }, + "time": "2022-09-21T11:38:17+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.19", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-11-18T07:47:47+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.26", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2", + "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.5", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.2", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2022-10-28T06:00:21+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^5.4@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", + "keywords": [ + "container", + "dependency injection" + ], + "support": { + "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" + }, + "time": "2021-10-28T11:13:42+00:00" + }, + { + "name": "pleonasm/merkle-tree", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/pleonasm/merkle-tree.git", + "reference": "9ddc9d0a0e396750fada378f3aa90f6c02dd56a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pleonasm/merkle-tree/zipball/9ddc9d0a0e396750fada378f3aa90f6c02dd56a1", + "reference": "9ddc9d0a0e396750fada378f3aa90f6c02dd56a1", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "ext-xdebug": ">=2.2.0", + "phpunit/php-invoker": ">=1.0.0,<1.2.0", + "phpunit/phpunit": "3.7.19", + "satooshi/php-coveralls": "*@dev", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Pleo": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Matthew Nagi", + "email": "matthew.nagi@base-2.net" + } + ], + "description": "An implementation of a Merkle Tree in PHP", + "support": { + "issues": "https://github.com/pleonasm/merkle-tree/issues", + "source": "https://github.com/pleonasm/merkle-tree/tree/master" + }, + "time": "2013-05-22T20:46:20+00:00" + }, + { + "name": "pragmarx/google2fa", + "version": "v8.0.1", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "reference": "80c3d801b31fe165f8fe99ea085e0a37834e1be3", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1.0|^2.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.18", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PragmaRX\\Google2FA\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.1" + }, + "time": "2022-06-13T21:57:56+00:00" + }, + { + "name": "pragmarx/google2fa-laravel", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-laravel.git", + "reference": "d8243b8f812472f1112716c5462157e0ec128fce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-laravel/zipball/d8243b8f812472f1112716c5462157e0ec128fce", + "reference": "d8243b8f812472f1112716c5462157e0ec128fce", + "shasum": "" + }, + "require": { + "laravel/framework": ">=5.4.36|^8.0|^9.0", + "php": ">=7.0", + "pragmarx/google2fa-qrcode": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*|5.*|6.*", + "phpunit/phpunit": "~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "Required to generate inline QR Codes.", + "pragmarx/recovery": "Generate recovery codes." + }, + "type": "library", + "extra": { + "component": "package", + "frameworks": [ + "Laravel" + ], + "branch-alias": { + "dev-master": "0.2-dev" + }, + "laravel": { + "providers": [ + "PragmaRX\\Google2FALaravel\\ServiceProvider" + ], + "aliases": { + "Google2FA": "PragmaRX\\Google2FALaravel\\Facade" + } + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FALaravel\\": "src/", + "PragmaRX\\Google2FALaravel\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "keywords": [ + "Authentication", + "Two Factor Authentication", + "google2fa", + "laravel" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-laravel/issues", + "source": "https://github.com/antonioribeiro/google2fa-laravel/tree/v2.0.2" + }, + "time": "2022-03-08T18:03:04+00:00" + }, + { + "name": "pragmarx/google2fa-qrcode", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/antonioribeiro/google2fa-qrcode.git", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antonioribeiro/google2fa-qrcode/zipball/ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "reference": "ce4d8a729b6c93741c607cfb2217acfffb5bf76b", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "pragmarx/google2fa": ">=4.0" + }, + "require-dev": { + "bacon/bacon-qr-code": "^2.0", + "chillerlan/php-qrcode": "^1.0|^2.0|^3.0|^4.0", + "khanamiryan/qrcode-detector-decoder": "^1.0", + "phpunit/phpunit": "~4|~5|~6|~7|~8|~9" + }, + "suggest": { + "bacon/bacon-qr-code": "For QR Code generation, requires imagick", + "chillerlan/php-qrcode": "For QR Code generation" + }, + "type": "library", + "extra": { + "component": "package", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PragmaRX\\Google2FAQRCode\\": "src/", + "PragmaRX\\Google2FAQRCode\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" + } + ], + "description": "QR Code package for Google2FA", + "keywords": [ + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa", + "qr code", + "qrcode" + ], + "support": { + "issues": "https://github.com/antonioribeiro/google2fa-qrcode/issues", + "source": "https://github.com/antonioribeiro/google2fa-qrcode/tree/v3.0.0" + }, + "time": "2021-08-15T12:53:48+00:00" + }, + { + "name": "predis/predis", + "version": "v1.1.10", + "source": { + "type": "git", + "url": "https://github.com/predis/predis.git", + "reference": "a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/predis/predis/zipball/a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e", + "reference": "a2fb02d738bedadcffdbb07efa3a5e7bd57f8d6e", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-curl": "Allows access to Webdis when paired with phpiredis", + "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniele Alessandri", + "email": "suppakilla@gmail.com", + "homepage": "http://clorophilla.net", + "role": "Creator & Maintainer" + }, + { + "name": "Till Krüss", + "homepage": "https://till.im", + "role": "Maintainer" + } + ], + "description": "Flexible and feature-complete Redis client for PHP and HHVM", + "homepage": "http://github.com/predis/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "support": { + "issues": "https://github.com/predis/predis/issues", + "source": "https://github.com/predis/predis/tree/v1.1.10" + }, + "funding": [ + { + "url": "https://github.com/sponsors/tillkruss", + "type": "github" + } + ], + "time": "2022-01-05T17:46:08+00:00" + }, + { + "name": "propaganistas/laravel-fakeid", + "version": "4.0.10", + "source": { + "type": "git", + "url": "https://github.com/Propaganistas/Laravel-FakeId.git", + "reference": "1dd1511b8c0555eacbeab8cd717bf5dd387efee3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Propaganistas/Laravel-FakeId/zipball/1dd1511b8c0555eacbeab8cd717bf5dd387efee3", + "reference": "1dd1511b8c0555eacbeab8cd717bf5dd387efee3", + "shasum": "" + }, + "require": { + "illuminate/config": "^6.0|^7.0|^8.0|^9.0", + "illuminate/container": "^6.0|^7.0|^8.0|^9.0", + "illuminate/routing": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "jenssegers/optimus": "^1.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "orchestra/testbench": "*", + "phpunit/phpunit": "*" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Propaganistas\\LaravelFakeId\\FakeIdServiceProvider" + ], + "aliases": { + "FakeId": "Propaganistas\\LaravelFakeId\\Facades\\FakeId" + } + } + }, + "autoload": { + "psr-4": { + "Propaganistas\\LaravelFakeId\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Propaganistas", + "email": "Propaganistas@users.noreply.github.com" + } + ], + "description": "Automatic ID obfuscation for Eloquent models.", + "keywords": [ + "fakeid", + "hashids", + "laravel", + "obfuscation", + "optimus" + ], + "support": { + "issues": "https://github.com/Propaganistas/Laravel-FakeId/issues", + "source": "https://github.com/Propaganistas/Laravel-FakeId/tree/4.0.10" + }, + "time": "2022-10-13T12:58:01+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.11.9", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "1acec99d6684a54ff92f8b548a4e41b566963778" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/1acec99d6684a54ff92f8b548a4e41b566963778", + "reference": "1acec99d6684a54ff92f8b548a4e41b566963778", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.9" + }, + "time": "2022-11-06T15:29:46+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-10-10T03:01:02+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.6.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/ad63bc700e7d021039e30ce464eba384c4a1d40f", + "reference": "ad63bc700e7d021039e30ce464eba384c4a1d40f", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.6.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2022-11-05T23:03:38+00:00" + }, + { + "name": "rector/rector", + "version": "0.14.8", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "46ee9a173a2b2645ca92a75ffc17460139fa226e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/46ee9a173a2b2645ca92a75ffc17460139fa226e", + "reference": "46ee9a173a2b2645ca92a75ffc17460139fa226e", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-php-parser": "*", + "rector/rector-phpoffice": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.14-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.14.8" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-11-14T14:09:49+00:00" + }, + { + "name": "ruafozy/mersenne-twister", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/ruafozy/php-mersenne-twister.git", + "reference": "83ca113aa1e5f924d3b5f03679b1480063cc7d94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ruafozy/php-mersenne-twister/zipball/83ca113aa1e5f924d3b5f03679b1480063cc7d94", + "reference": "83ca113aa1e5f924d3b5f03679b1480063cc7d94", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/mersenne_twister.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Pure-PHP Mersenne Twister", + "homepage": "https://github.com/ruafozy/php-mersenne-twister", + "keywords": [ + "PRNG", + "mersenne", + "random" + ], + "support": { + "issues": "https://github.com/ruafozy/php-mersenne-twister/issues", + "source": "https://github.com/ruafozy/php-mersenne-twister/tree/master" + }, + "time": "2015-02-21T10:26:45+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "sentry/sdk", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php-sdk.git", + "reference": "d0678fc7274dbb03046ed05cb24eb92945bedf8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php-sdk/zipball/d0678fc7274dbb03046ed05cb24eb92945bedf8e", + "reference": "d0678fc7274dbb03046ed05cb24eb92945bedf8e", + "shasum": "" + }, + "require": { + "http-interop/http-factory-guzzle": "^1.0", + "sentry/sentry": "^3.9", + "symfony/http-client": "^4.3|^5.0|^6.0" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "This is a metapackage shipping sentry/sentry with a recommended HTTP client.", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "sentry" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-php-sdk/issues", + "source": "https://github.com/getsentry/sentry-php-sdk/tree/3.3.0" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2022-10-11T09:05:00+00:00" + }, + { + "name": "sentry/sentry", + "version": "3.12.0", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php.git", + "reference": "4902f43640963ed45517fd7c1da7fdd5511bb304" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/4902f43640963ed45517fd7c1da7fdd5511bb304", + "reference": "4902f43640963ed45517fd7c1da7fdd5511bb304", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", + "jean85/pretty-package-versions": "^1.5|^2.0.4", + "php": "^7.2|^8.0", + "php-http/async-client-implementation": "^1.0", + "php-http/client-common": "^1.5|^2.0", + "php-http/discovery": "^1.11", + "php-http/httplug": "^1.1|^2.0", + "php-http/message": "^1.5", + "psr/http-factory": "^1.0", + "psr/http-message-implementation": "^1.0", + "psr/log": "^1.0|^2.0|^3.0", + "symfony/options-resolver": "^3.4.43|^4.4.30|^5.0.11|^6.0", + "symfony/polyfill-php80": "^1.17" + }, + "conflict": { + "php-http/client-common": "1.8.0", + "raven/raven": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.19|3.4.*", + "http-interop/http-factory-guzzle": "^1.0", + "monolog/monolog": "^1.6|^2.0|^3.0", + "nikic/php-parser": "^4.10.3", + "php-http/mock-client": "^1.3", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5.14|^9.4", + "symfony/phpunit-bridge": "^5.2|^6.0", + "vimeo/psalm": "^4.17" + }, + "suggest": { + "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Sentry\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "A PHP SDK for Sentry (http://sentry.io)", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "sentry" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-php/issues", + "source": "https://github.com/getsentry/sentry-php/tree/3.12.0" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2022-11-22T10:57:08+00:00" + }, + { + "name": "sentry/sentry-laravel", + "version": "2.14.2", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-laravel.git", + "reference": "4538ed31d77868dd3b6d72ad6e5e68b572beeb9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/4538ed31d77868dd3b6d72ad6e5e68b572beeb9f", + "reference": "4538ed31d77868dd3b6d72ad6e5e68b572beeb9f", + "shasum": "" + }, + "require": { + "illuminate/support": "5.0 - 5.8 | ^6.0 | ^7.0 | ^8.0 | ^9.0", + "nyholm/psr7": "^1.0", + "php": "^7.2 | ^8.0", + "sentry/sdk": "^3.1", + "sentry/sentry": "^3.3", + "symfony/psr-http-message-bridge": "^1.0 | ^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11", + "laravel/framework": "5.0 - 5.8 | ^6.0 | ^7.0 | ^8.0 | ^9.0", + "mockery/mockery": "^1.3", + "orchestra/testbench": "3.1 - 3.8 | ^4.7 | ^5.1 | ^6.0 | ^7.0", + "phpunit/phpunit": "^5.7 | ^6.5 | ^7.5 | ^8.4 | ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev", + "dev-0.x": "0.x-dev" + }, + "laravel": { + "providers": [ + "Sentry\\Laravel\\ServiceProvider", + "Sentry\\Laravel\\Tracing\\ServiceProvider" + ], + "aliases": { + "Sentry": "Sentry\\Laravel\\Facade" + } + } + }, + "autoload": { + "psr-0": { + "Sentry\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "Laravel SDK for Sentry (https://sentry.io)", + "homepage": "https://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "laravel", + "log", + "logging", + "sentry" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-laravel/issues", + "source": "https://github.com/getsentry/sentry-laravel/tree/2.14.2" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2022-10-13T09:21:29+00:00" + }, + { + "name": "simplito/bigint-wrapper-php", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/simplito/bigint-wrapper-php.git", + "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplito/bigint-wrapper-php/zipball/cf21ec76d33f103add487b3eadbd9f5033a25930", + "reference": "cf21ec76d33f103add487b3eadbd9f5033a25930", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "BI\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simplito Team", + "email": "s.smyczynski@simplito.com", + "homepage": "https://simplito.com" + } + ], + "description": "Common interface for php_gmp and php_bcmath modules", + "support": { + "issues": "https://github.com/simplito/bigint-wrapper-php/issues", + "source": "https://github.com/simplito/bigint-wrapper-php/tree/1.0.0" + }, + "time": "2018-02-27T12:38:08+00:00" + }, + { + "name": "simplito/bn-php", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/simplito/bn-php.git", + "reference": "189167f940cdb681288a967b0f4d66de81adcd97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplito/bn-php/zipball/189167f940cdb681288a967b0f4d66de81adcd97", + "reference": "189167f940cdb681288a967b0f4d66de81adcd97", + "shasum": "" + }, + "require": { + "simplito/bigint-wrapper-php": "~1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "BN\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simplito Team", + "email": "s.smyczynski@simplito.com", + "homepage": "https://simplito.com" + } + ], + "description": "Big number implementation compatible with bn.js", + "support": { + "issues": "https://github.com/simplito/bn-php/issues", + "source": "https://github.com/simplito/bn-php/tree/1.1.3" + }, + "time": "2022-08-12T18:58:14+00:00" + }, + { + "name": "simplito/elliptic-php", + "version": "1.0.10", + "source": { + "type": "git", + "url": "https://github.com/simplito/elliptic-php.git", + "reference": "a6228f480c729cf8efe2650a617c8500e981716d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplito/elliptic-php/zipball/a6228f480c729cf8efe2650a617c8500e981716d", + "reference": "a6228f480c729cf8efe2650a617c8500e981716d", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "simplito/bn-php": "~1.1.0" + }, + "require-dev": { + "phpbench/phpbench": "@dev", + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Elliptic\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simplito Team", + "email": "s.smyczynski@simplito.com", + "homepage": "https://simplito.com" + } + ], + "description": "Fast elliptic curve cryptography", + "homepage": "https://github.com/simplito/elliptic-php", + "keywords": [ + "Curve25519", + "ECDSA", + "Ed25519", + "EdDSA", + "cryptography", + "curve", + "curve25519-weier", + "ecc", + "ecdh", + "elliptic", + "nistp192", + "nistp224", + "nistp256", + "nistp384", + "nistp521", + "secp256k1" + ], + "support": { + "issues": "https://github.com/simplito/elliptic-php/issues", + "source": "https://github.com/simplito/elliptic-php/tree/1.0.10" + }, + "time": "2022-08-12T19:00:25+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-11-09T10:57:15+00:00" + }, + { + "name": "spatie/data-transfer-object", + "version": "3.9.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/data-transfer-object.git", + "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8", + "reference": "1df0906c4e9e3aebd6c0506fd82c8b7d5548c1c8", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "illuminate/collections": "^8.36", + "jetbrains/phpstorm-attributes": "^1.0", + "larapack/dd": "^1.1", + "phpunit/phpunit": "^9.5.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\DataTransferObject\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brent Roose", + "email": "brent@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Data transfer objects with batteries included", + "homepage": "https://github.com/spatie/data-transfer-object", + "keywords": [ + "data-transfer-object", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/data-transfer-object/issues", + "source": "https://github.com/spatie/data-transfer-object/tree/3.9.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "abandoned": "spatie/laravel-data", + "time": "2022-09-16T13:34:38+00:00" + }, + { + "name": "spatie/db-dumper", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/db-dumper.git", + "reference": "129b8254b2c9f10881a754a692bd9507b09a1893" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/db-dumper/zipball/129b8254b2c9f10881a754a692bd9507b09a1893", + "reference": "129b8254b2c9f10881a754a692bd9507b09a1893", + "shasum": "" + }, + "require": { + "php": "^8.0", + "symfony/process": "^5.0|^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\DbDumper\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Dump databases", + "homepage": "https://github.com/spatie/db-dumper", + "keywords": [ + "database", + "db-dumper", + "dump", + "mysqldump", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/db-dumper/tree/3.3.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-09-01T20:20:26+00:00" + }, + { + "name": "spatie/image", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/image.git", + "reference": "c2dc137c52d17bf12aff94ad051370c0f106b322" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/image/zipball/c2dc137c52d17bf12aff94ad051370c0f106b322", + "reference": "c2dc137c52d17bf12aff94ad051370c0f106b322", + "shasum": "" + }, + "require": { + "ext-exif": "*", + "ext-json": "*", + "ext-mbstring": "*", + "league/glide": "^2.2.2", + "php": "^8.0", + "spatie/image-optimizer": "^1.1", + "spatie/temporary-directory": "^1.0|^2.0", + "symfony/process": "^3.0|^4.0|^5.0|^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/var-dumper": "^4.0|^5.0|^6.0", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Image\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Manipulate images with an expressive API", + "homepage": "https://github.com/spatie/image", + "keywords": [ + "image", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/image/tree/2.2.4" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-08-09T10:18:57+00:00" + }, + { + "name": "spatie/image-optimizer", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/image-optimizer.git", + "reference": "6db75529cbf8fa84117046a9d513f277aead90a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/6db75529cbf8fa84117046a9d513f277aead90a0", + "reference": "6db75529cbf8fa84117046a9d513f277aead90a0", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.3|^8.0", + "psr/log": "^1.0 | ^2.0 | ^3.0", + "symfony/process": "^4.2|^5.0|^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.21|^9.4.4", + "symfony/var-dumper": "^4.2|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ImageOptimizer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily optimize images using PHP", + "homepage": "https://github.com/spatie/image-optimizer", + "keywords": [ + "image-optimizer", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/image-optimizer/issues", + "source": "https://github.com/spatie/image-optimizer/tree/1.6.2" + }, + "time": "2021-12-21T10:08:05+00:00" + }, + { + "name": "spatie/laravel-activitylog", + "version": "4.7.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-activitylog.git", + "reference": "eee61436e2984119fd71fc338a45ec7d68e3b548" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-activitylog/zipball/eee61436e2984119fd71fc338a45ec7d68e3b548", + "reference": "eee61436e2984119fd71fc338a45ec7d68e3b548", + "shasum": "" + }, + "require": { + "illuminate/config": "^8.0 || ^9.0", + "illuminate/database": "^8.69 || ^9.27", + "illuminate/support": "^8.0 || ^9.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.6.3" + }, + "require-dev": { + "ext-json": "*", + "orchestra/testbench": "^6.23 || ^7.0", + "pestphp/pest": "^1.20" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Activitylog\\ActivitylogServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Activitylog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A very simple activity logger to monitor the users of your website or application", + "homepage": "https://github.com/spatie/activitylog", + "keywords": [ + "activity", + "laravel", + "log", + "spatie", + "user" + ], + "support": { + "issues": "https://github.com/spatie/laravel-activitylog/issues", + "source": "https://github.com/spatie/laravel-activitylog/tree/4.7.2" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-11-14T12:16:46+00:00" + }, + { + "name": "spatie/laravel-backup", + "version": "8.1.5", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-backup.git", + "reference": "cf367fbe50ff3b1ae9a79638cc5ef66f3cc9c7fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-backup/zipball/cf367fbe50ff3b1ae9a79638cc5ef66f3cc9c7fa", + "reference": "cf367fbe50ff3b1ae9a79638cc5ef66f3cc9c7fa", + "shasum": "" + }, + "require": { + "ext-zip": "^1.14.0", + "illuminate/console": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/events": "^9.0", + "illuminate/filesystem": "^9.0", + "illuminate/notifications": "^9.0", + "illuminate/support": "^9.0", + "league/flysystem": "^3.0", + "php": "^8.0", + "spatie/db-dumper": "^3.0", + "spatie/laravel-package-tools": "^1.6.2", + "spatie/laravel-signal-aware-command": "^1.2", + "spatie/temporary-directory": "^2.0", + "symfony/console": "^6.0", + "symfony/finder": "^6.0" + }, + "require-dev": { + "composer-runtime-api": "^2.0", + "ext-pcntl": "*", + "laravel/slack-notification-channel": "^2.4", + "league/flysystem-aws-s3-v3": "^2.0|^3.0", + "mockery/mockery": "^1.4", + "nunomaduro/larastan": "^2.1", + "orchestra/testbench": "^7.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.1" + }, + "suggest": { + "laravel/slack-notification-channel": "Required for sending notifications via Slack" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Backup\\BackupServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Helpers/functions.php" + ], + "psr-4": { + "Spatie\\Backup\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A Laravel package to backup your application", + "homepage": "https://github.com/spatie/laravel-backup", + "keywords": [ + "backup", + "database", + "laravel-backup", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-backup/issues", + "source": "https://github.com/spatie/laravel-backup/tree/8.1.5" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2022-10-19T13:01:58+00:00" + }, + { + "name": "spatie/laravel-flash", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-flash.git", + "reference": "4bdb9b46b1b4604a2a67e2c6be915557905c31ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-flash/zipball/4bdb9b46b1b4604a2a67e2c6be915557905c31ff", + "reference": "4bdb9b46b1b4604a2a67e2c6be915557905c31ff", + "shasum": "" + }, + "require": { + "illuminate/session": "^8.0|^9.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "orchestra/testbench": "^6.23|^7.0", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Flash\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A lightweight package to flash messages", + "homepage": "https://github.com/spatie/laravel-flash", + "keywords": [ + "laravel-flash", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-flash/issues", + "source": "https://github.com/spatie/laravel-flash/tree/1.9.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-01-12T08:17:47+00:00" + }, + { + "name": "spatie/laravel-honeypot", + "version": "4.3.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-honeypot.git", + "reference": "8879f1952c1d8a733f9b9eab439340597bcfb1ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-honeypot/zipball/8879f1952c1d8a733f9b9eab439340597bcfb1ac", + "reference": "8879f1952c1d8a733f9b9eab439340597bcfb1ac", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0", + "illuminate/encryption": "^8.0|^9.0", + "illuminate/http": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "illuminate/validation": "^8.0|^9.0", + "nesbot/carbon": "^2.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9", + "symfony/http-foundation": "^5.1.2|^6.0" + }, + "require-dev": { + "livewire/livewire": "^2.10", + "orchestra/testbench": "^6.23|^7.0", + "phpunit/phpunit": "^9.4", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Honeypot\\HoneypotServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\Honeypot\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Preventing spam submitted through forms", + "homepage": "https://github.com/spatie/laravel-honeypot", + "keywords": [ + "laravel-honeypot", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/laravel-honeypot/tree/4.3.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-08-03T22:31:36+00:00" + }, + { + "name": "spatie/laravel-medialibrary", + "version": "10.7.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-medialibrary.git", + "reference": "40cf0c63286926f7357eb8136c0d2325cf33ba29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/40cf0c63286926f7357eb8136c0d2325cf33ba29", + "reference": "40cf0c63286926f7357eb8136c0d2325cf33ba29", + "shasum": "" + }, + "require": { + "ext-exif": "*", + "ext-fileinfo": "*", + "ext-json": "*", + "illuminate/bus": "^9.18", + "illuminate/console": "^9.18", + "illuminate/database": "^9.18", + "illuminate/pipeline": "^9.18", + "illuminate/support": "^9.18", + "intervention/image": "^2.7", + "maennchen/zipstream-php": "^2.0", + "php": "^8.0", + "spatie/image": "^2.2.2", + "spatie/temporary-directory": "^2.0", + "symfony/console": "^6.0" + }, + "conflict": { + "php-ffmpeg/php-ffmpeg": "<0.6.1" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.133.11", + "doctrine/dbal": "^2.13", + "ext-imagick": "*", + "ext-pdo_sqlite": "*", + "ext-zip": "*", + "guzzlehttp/guzzle": "^7.4", + "league/flysystem-aws-s3-v3": "^3.0", + "mockery/mockery": "^1.4", + "nunomaduro/larastan": "^2.0", + "orchestra/testbench": "7.*", + "pestphp/pest": "^1.21", + "phpstan/extension-installer": "^1.1", + "spatie/laravel-ray": "^1.28", + "spatie/pdf-to-image": "^2.1", + "spatie/phpunit-snapshot-assertions": "^4.2" + }, + "suggest": { + "league/flysystem-aws-s3-v3": "Required to use AWS S3 file storage", + "php-ffmpeg/php-ffmpeg": "Required for generating video thumbnails", + "spatie/pdf-to-image": "Required for generating thumbsnails of PDFs and SVGs" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\MediaLibrary\\MediaLibraryServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\MediaLibrary\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Associate files with Eloquent models", + "homepage": "https://github.com/spatie/laravel-medialibrary", + "keywords": [ + "cms", + "conversion", + "downloads", + "images", + "laravel", + "laravel-medialibrary", + "media", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-medialibrary/issues", + "source": "https://github.com/spatie/laravel-medialibrary/tree/10.7.2" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-11-22T17:02:33+00:00" + }, + { + "name": "spatie/laravel-model-status", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-model-status.git", + "reference": "6380fa82ac98ab755b08a034d2c1608212e26478" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-model-status/zipball/6380fa82ac98ab755b08a034d2c1608212e26478", + "reference": "6380fa82ac98ab755b08a034d2c1608212e26478", + "shasum": "" + }, + "require": { + "illuminate/support": "^8.71|^9.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^6.23|^7.0", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\ModelStatus\\ModelStatusServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\ModelStatus\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Thomas Verhelst", + "email": "tvke91@gmail.com", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A package to enable assigning statuses to Eloquent Models", + "homepage": "https://github.com/spatie/laravel-model-status", + "keywords": [ + "laravel-status", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-model-status/issues", + "source": "https://github.com/spatie/laravel-model-status/tree/1.11.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-02-03T07:36:04+00:00" + }, + { + "name": "spatie/laravel-newsletter", + "version": "4.11.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-newsletter.git", + "reference": "25e456abecaba25e20d1c11e934bdc3f89601245" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-newsletter/zipball/25e456abecaba25e20d1c11e934bdc3f89601245", + "reference": "25e456abecaba25e20d1c11e934bdc3f89601245", + "shasum": "" + }, + "require": { + "drewm/mailchimp-api": "^2.4", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Newsletter\\NewsletterServiceProvider" + ], + "aliases": { + "Newsletter": "Spatie\\Newsletter\\NewsletterFacade" + } + } + }, + "autoload": { + "psr-4": { + "Spatie\\Newsletter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Manage newsletters in Laravel", + "homepage": "https://github.com/spatie/laravel-newsletter", + "keywords": [ + "laravel", + "mailchimp", + "newsletter" + ], + "support": { + "issues": "https://github.com/spatie/laravel-newsletter/issues", + "source": "https://github.com/spatie/laravel-newsletter/tree/4.11.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-01-14T07:31:45+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.13.7", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "4af8e608184471b5568af6265ebb0ca0025c131a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/4af8e608184471b5568af6265ebb0ca0025c131a", + "reference": "4af8e608184471b5568af6265ebb0ca0025c131a", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.28", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^7.7", + "pestphp/pest": "^1.22", + "phpunit/phpunit": "^9.5.24", + "spatie/pest-plugin-test-time": "^1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.13.7" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-11-15T09:10:09+00:00" + }, + { + "name": "spatie/laravel-personal-data-export", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-personal-data-export.git", + "reference": "49db4b7617e32e94027784c358f426b994560d4b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-personal-data-export/zipball/49db4b7617e32e94027784c358f426b994560d4b", + "reference": "49db4b7617e32e94027784c358f426b994560d4b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-zip": "*", + "illuminate/filesystem": "^9.0", + "illuminate/queue": "^9.0", + "illuminate/support": "^9.0", + "nesbot/carbon": "^2.14", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9", + "spatie/temporary-directory": "^2.0" + }, + "require-dev": { + "laravel/legacy-factories": "^1.0.4", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^7.0", + "spatie/invade": "^1.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\PersonalDataExport\\PersonalDataExportServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\PersonalDataExport\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Create personal data downloads in a Laravel app", + "homepage": "https://github.com/spatie/laravel-personal-data-export", + "keywords": [ + "gdpr", + "personal", + "personal-data-export", + "spatie", + "zip" + ], + "support": { + "issues": "https://github.com/spatie/laravel-personal-data-export/issues", + "source": "https://github.com/spatie/laravel-personal-data-export/tree/4.2.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-07-06T16:39:04+00:00" + }, + { + "name": "spatie/laravel-ray", + "version": "1.31.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ray.git", + "reference": "7394694afd89d05879e7a69c54abab73c1199acd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/7394694afd89d05879e7a69c54abab73c1199acd", + "reference": "7394694afd89d05879e7a69c54abab73c1199acd", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/contracts": "^7.20|^8.19|^9.0", + "illuminate/database": "^7.20|^8.19|^9.0", + "illuminate/queue": "^7.20|^8.19|^9.0", + "illuminate/support": "^7.20|^8.19|^9.0", + "php": "^7.3|^8.0", + "spatie/backtrace": "^1.0", + "spatie/ray": "^1.33", + "symfony/stopwatch": "4.2|^5.1|^6.0", + "zbateson/mail-mime-parser": "^1.3.1|^2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.3", + "laravel/framework": "^7.20|^8.19|^9.0", + "orchestra/testbench-core": "^5.0|^6.0|^7.0", + "phpstan/phpstan": "^0.12.93", + "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.29.x-dev" + }, + "laravel": { + "providers": [ + "Spatie\\LaravelRay\\RayServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\LaravelRay\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily debug Laravel apps", + "homepage": "https://github.com/spatie/laravel-ray", + "keywords": [ + "laravel-ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-ray/issues", + "source": "https://github.com/spatie/laravel-ray/tree/1.31.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2022-09-20T13:13:22+00:00" + }, + { + "name": "spatie/laravel-responsecache", + "version": "7.4.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-responsecache.git", + "reference": "48cb5af1d80e023761ac4c93963cfc7d5adaa38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-responsecache/zipball/48cb5af1d80e023761ac4c93963cfc7d5adaa38b", + "reference": "48cb5af1d80e023761ac4c93963cfc7d5adaa38b", + "shasum": "" + }, + "require": { + "illuminate/cache": "^8.71|^9.0", + "illuminate/console": "^8.71|^9.0", + "illuminate/container": "^8.71|^9.0", + "illuminate/http": "^8.71|^9.0", + "illuminate/support": "^8.71|^9.0", + "nesbot/carbon": "^2.63", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9" + }, + "require-dev": { + "laravel/framework": "^9.0", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^6.23|^7.0", + "pestphp/pest": "^1.22", + "phpunit/phpunit": "^9.4" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\ResponseCache\\ResponseCacheServiceProvider" + ], + "aliases": { + "ResponseCache": "Spatie\\ResponseCache\\Facades\\ResponseCache" + } + } + }, + "autoload": { + "psr-4": { + "Spatie\\ResponseCache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Speed up a Laravel application by caching the entire response", + "homepage": "https://github.com/spatie/laravel-responsecache", + "keywords": [ + "cache", + "laravel", + "laravel-responsecache", + "performance", + "response", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/laravel-responsecache/tree/7.4.4" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-11-25T08:07:24+00:00" + }, + { + "name": "spatie/laravel-schemaless-attributes", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-schemaless-attributes.git", + "reference": "3ac6d63f36c631edfafa5f34d7a3885f47b96e48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-schemaless-attributes/zipball/3ac6d63f36c631edfafa5f34d7a3885f47b96e48", + "reference": "3ac6d63f36c631edfafa5f34d7a3885f47b96e48", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^7.0|^8.0|^9.0", + "illuminate/database": "^7.0|^8.0|^9.0", + "illuminate/support": "^7.0|^8.0|^9.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.4.3" + }, + "require-dev": { + "brianium/paratest": "^6.2", + "mockery/mockery": "^1.4", + "nunomaduro/collision": "^5.3|^6.0", + "orchestra/testbench": "^6.15|^7.0", + "phpunit/phpunit": "^9.5.4" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\SchemalessAttributes\\SchemalessAttributesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\SchemalessAttributes\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Add schemaless attributes to Eloquent models", + "homepage": "https://github.com/spatie/laravel-schemaless-attributes", + "keywords": [ + "laravel-schemaless-attributes", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-schemaless-attributes/issues", + "source": "https://github.com/spatie/laravel-schemaless-attributes/tree/2.3.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-01-12T08:21:28+00:00" + }, + { + "name": "spatie/laravel-signal-aware-command", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-signal-aware-command.git", + "reference": "d15a5b69bf715fc557b7034b4abd5a1472ae7ec8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-signal-aware-command/zipball/d15a5b69bf715fc557b7034b4abd5a1472ae7ec8", + "reference": "d15a5b69bf715fc557b7034b4abd5a1472ae7ec8", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.35|^9.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.4.3" + }, + "require-dev": { + "brianium/paratest": "^6.2", + "ext-pcntl": "*", + "nunomaduro/collision": "^5.3|^6.0", + "orchestra/testbench": "^6.16|^7.0", + "phpunit/phpunit": "^9.5", + "spatie/laravel-ray": "^1.17" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\SignalAwareCommand\\SignalAwareCommandServiceProvider" + ], + "aliases": { + "Signal": "Spatie\\SignalAwareCommand\\Facades\\Signal" + } + } + }, + "autoload": { + "psr-4": { + "Spatie\\SignalAwareCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Handle signals in artisan commands", + "homepage": "https://github.com/spatie/laravel-signal-aware-command", + "keywords": [ + "laravel", + "laravel-signal-aware-command", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-signal-aware-command/issues", + "source": "https://github.com/spatie/laravel-signal-aware-command/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-01-12T19:42:44+00:00" + }, + { + "name": "spatie/laravel-sluggable", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-sluggable.git", + "reference": "e3b102ef0f0a0bfbba1eca5961a8e33207c76028" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-sluggable/zipball/e3b102ef0f0a0bfbba1eca5961a8e33207c76028", + "reference": "e3b102ef0f0a0bfbba1eca5961a8e33207c76028", + "shasum": "" + }, + "require": { + "illuminate/database": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^6.23|^7.0", + "pestphp/pest": "^1.20", + "spatie/laravel-translatable": "^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Sluggable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Generate slugs when saving Eloquent models", + "homepage": "https://github.com/spatie/laravel-sluggable", + "keywords": [ + "laravel-sluggable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-sluggable/issues", + "source": "https://github.com/spatie/laravel-sluggable/tree/3.4.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-03-28T11:21:33+00:00" + }, + { + "name": "spatie/macroable", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/2.0.0" + }, + "time": "2021-03-26T22:39:02+00:00" + }, + { + "name": "spatie/pest-plugin-snapshots", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/pest-plugin-snapshots.git", + "reference": "7932ba9a44f9c5d010bcda4dc06ceb0474e13d6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/pest-plugin-snapshots/zipball/7932ba9a44f9c5d010bcda4dc06ceb0474e13d6d", + "reference": "7932ba9a44f9c5d010bcda4dc06ceb0474e13d6d", + "shasum": "" + }, + "require": { + "pestphp/pest": "^1.0", + "php": "^7.4 || ^8.0", + "spatie/phpunit-snapshot-assertions": "^4.2.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Spatie\\Snapshots\\Concerns\\": "./src/Concerns/" + }, + "exclude-from-classmap": [ + "../phpunit-snapshot-assertions/src/Concerns/SnapshotDirectoryAware.php", + "../phpunit-snapshot-assertions/src/Concerns/SnapshotIdAware.php", + "vendor/spatie/phpunit-snapshot-assertions/src/Concerns/SnapshotDirectoryAware.php", + "vendor/spatie/phpunit-snapshot-assertions/src/Concerns/SnapshotIdAware.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A package for snapshot testing in Pest", + "homepage": "https://github.com/spatie/pest-plugin-snapshots", + "keywords": [ + "pest", + "plugin", + "snapshots", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/pest-plugin-snapshots/issues", + "source": "https://github.com/spatie/pest-plugin-snapshots/tree/1.1.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2021-07-08T18:00:48+00:00" + }, + { + "name": "spatie/phpunit-snapshot-assertions", + "version": "4.2.16", + "source": { + "type": "git", + "url": "https://github.com/spatie/phpunit-snapshot-assertions.git", + "reference": "4c325139313c06b656ba10d5b60306c0de728c1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/phpunit-snapshot-assertions/zipball/4c325139313c06b656ba10d5b60306c0de728c1f", + "reference": "4c325139313c06b656ba10d5b60306c0de728c1f", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "php": "^7.3|^7.4|^8.0", + "phpunit/phpunit": "^8.3|^9.0", + "symfony/property-access": "^4.0|^5.0|^6.0", + "symfony/serializer": "^4.0|^5.0|^6.0", + "symfony/yaml": "^4.0|^5.0|^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Snapshots\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Snapshot testing with PHPUnit", + "homepage": "https://github.com/spatie/phpunit-snapshot-assertions", + "keywords": [ + "assert", + "phpunit", + "phpunit-snapshot-assertions", + "snapshot", + "spatie", + "testing" + ], + "support": { + "issues": "https://github.com/spatie/phpunit-snapshot-assertions/issues", + "source": "https://github.com/spatie/phpunit-snapshot-assertions/tree/4.2.16" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2022-10-10T15:58:50+00:00" + }, + { + "name": "spatie/ray", + "version": "1.36.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "4a4def8cda4806218341b8204c98375aa8c34323" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/4a4def8cda4806218341b8204c98375aa8c34323", + "reference": "4a4def8cda4806218341b8204c98375aa8c34323", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0|^2.0", + "symfony/stopwatch": "^4.0|^5.1|^6.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18|^9.0", + "nesbot/carbon": "^2.43", + "phpstan/phpstan": "^0.12.92", + "phpunit/phpunit": "^9.5", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Ray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.36.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2022-08-11T14:04:18+00:00" + }, + { + "name": "spatie/regex", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/regex.git", + "reference": "d543de2019a0068e7b80da0ba24f1c51c7469303" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/regex/zipball/d543de2019a0068e7b80da0ba24f1c51c7469303", + "reference": "d543de2019a0068e7b80da0ba24f1c51c7469303", + "shasum": "" + }, + "require": { + "php": "^8.0|^8.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Regex\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A sane interface for php's built in preg_* functions", + "homepage": "https://github.com/spatie/regex", + "keywords": [ + "expression", + "expressions", + "regex", + "regular", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/regex/issues", + "source": "https://github.com/spatie/regex/tree/3.1.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2021-11-30T21:13:59+00:00" + }, + { + "name": "spatie/temporary-directory", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/temporary-directory.git", + "reference": "e2818d871783d520b319c2d38dc37c10ecdcde20" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/e2818d871783d520b319c2d38dc37c10ecdcde20", + "reference": "e2818d871783d520b319c2d38dc37c10ecdcde20", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\TemporaryDirectory\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily create, use and destroy temporary directories", + "homepage": "https://github.com/spatie/temporary-directory", + "keywords": [ + "php", + "spatie", + "temporary-directory" + ], + "support": { + "issues": "https://github.com/spatie/temporary-directory/issues", + "source": "https://github.com/spatie/temporary-directory/tree/2.1.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-08-23T07:15:15+00:00" + }, + { + "name": "spatie/yaml-front-matter", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/spatie/yaml-front-matter.git", + "reference": "f49f228994de70827ca857efffdd3bd7703aea34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/f49f228994de70827ca857efffdd3bd7703aea34", + "reference": "f49f228994de70827ca857efffdd3bd7703aea34", + "shasum": "" + }, + "require": { + "php": "^7.0|^8.0", + "symfony/yaml": "^3.0|^4.0|^5.0|^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\YamlFrontMatter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A to the point yaml front matter parser", + "homepage": "https://github.com/sebastiandedeyne/yaml-front-matter", + "keywords": [ + "front matter", + "jekyll", + "spatie", + "yaml" + ], + "support": { + "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.7" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-04-06T12:03:55+00:00" + }, + { + "name": "staudenmeir/belongs-to-through", + "version": "v2.12.1", + "source": { + "type": "git", + "url": "https://github.com/staudenmeir/belongs-to-through.git", + "reference": "8316d274db603f63b16bb1c67379b0fa73209d98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staudenmeir/belongs-to-through/zipball/8316d274db603f63b16bb1c67379b0fa73209d98", + "reference": "8316d274db603f63b16bb1c67379b0fa73209d98", + "shasum": "" + }, + "require": { + "illuminate/database": "^9.0", + "php": "^8.0.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Znck\\Eloquent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rahul Kadyan", + "email": "hi@znck.me" + }, + { + "name": "Jonas Staudenmeir", + "email": "mail@jonas-staudenmeir.de" + } + ], + "description": "Laravel Eloquent BelongsToThrough relationships", + "support": { + "issues": "https://github.com/staudenmeir/belongs-to-through/issues", + "source": "https://github.com/staudenmeir/belongs-to-through/tree/v2.12.1" + }, + "funding": [ + { + "url": "https://paypal.me/JonasStaudenmeir", + "type": "custom" + } + ], + "time": "2022-03-10T21:14:19+00:00" + }, + { + "name": "symfony/console", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "a1282bd0c096e0bdb8800b104177e2ce404d8815" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a1282bd0c096e0bdb8800b104177e2ce404d8815", + "reference": "a1282bd0c096e0bdb8800b104177e2ce404d8815", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-26T21:42:49+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "699a26ce5ec656c198bf6e26398b0f0818c7e504" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/699a26ce5ec656c198bf6e26398b0f0818c7e504", + "reference": "699a26ce5ec656c198bf6e26398b0f0818c7e504", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T16:23:08+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-05T16:51:07+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "4d216a2beef096edf040a070117c39ca2abce307" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4d216a2beef096edf040a070117c39ca2abce307", + "reference": "4d216a2beef096edf040a070117c39ca2abce307", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-21T20:29:40+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-07-29T07:42:06+00:00" + }, + { + "name": "symfony/http-client", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "f515d066728774efb34347a87580621416ca8968" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/f515d066728774efb34347a87580621416ca8968", + "reference": "f515d066728774efb34347a87580621416ca8968", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/http-client-contracts": "^3", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-client/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T16:23:08+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fd038f08c623ab5d22b26e9ba35afe8c79071800", + "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-22T07:30:54+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "792a1856d2b95273f0e1c3435785f1d01a60ecc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/792a1856d2b95273f0e1c3435785f1d01a60ecc6", + "reference": "792a1856d2b95273f0e1c3435785f1d01a60ecc6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-12T09:44:59+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "8fc1ffe753948c47a103a809cdd6a4a8458b3254" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8fc1ffe753948c47a103a809cdd6a4a8458b3254", + "reference": "8fc1ffe753948c47a103a809cdd6a4a8458b3254", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^6.1", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.1", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^6.1", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^6.1", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T18:06:36+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "7e19813c0b43387c55665780c4caea505cc48391" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/7e19813c0b43387c55665780c4caea505cc48391", + "reference": "7e19813c0b43387c55665780c4caea505cc48391", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3" + }, + "conflict": { + "symfony/http-kernel": "<5.4" + }, + "require-dev": { + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/messenger": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T16:23:08+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "f440f066d57691088d998d6e437ce98771144618" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/f440f066d57691088d998d6e437ce98771144618", + "reference": "f440f066d57691088d998d6e437ce98771144618", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^5.2|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-19T08:10:53+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "927013f3aac555983a5059aada98e1907d842695" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/927013f3aac555983a5059aada98e1907d842695", + "reference": "927013f3aac555983a5059aada98e1907d842695", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-iconv": "*" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/f3cf1a645c2734236ed1e2e671e273eeb3586166", + "reference": "f3cf1a645c2734236ed1e2e671e273eeb3586166", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v6.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/a6506e99cfad7059b1ab5cab395854a0a0c21292", + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/property-access", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "cf034c0d8d25ed285bb8f6c2528ce6fac98563eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/cf034c0d8d25ed285bb8f6c2528ce6fac98563eb", + "reference": "cf034c0d8d25ed285bb8f6c2528ce6fac98563eb", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/property-info": "^5.4|^6.0" + }, + "require-dev": { + "symfony/cache": "^5.4|^6.0" + }, + "suggest": { + "psr/cache-implementation": "To cache access methods." + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T16:23:08+00:00" + }, + { + "name": "symfony/property-info", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "b5a46ec66a4b77d4bd39d58c22710be888e55b68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/b5a46ec66a4b77d4bd39d58c22710be888e55b68", + "reference": "b5a46ec66a4b77d4bd39d58c22710be888e55b68", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/dependency-injection": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.10.4", + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "suggest": { + "phpdocumentor/reflection-docblock": "To use the PHPDoc", + "psr/cache-implementation": "To cache results", + "symfony/doctrine-bridge": "To use Doctrine metadata", + "symfony/serializer": "To use Serializer metadata" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-28T16:23:08+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", + "reference": "d444f85dddf65c7e57c58d8e5b3a4dbb593b1840", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/config": "^4.4 || ^5.0 || ^6.0", + "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4@dev || ^6.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-05T10:34:54+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "95effeb9d6e2cec861cee06bf5bbf82d09aea7f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/95effeb9d6e2cec861cee06bf5bbf82d09aea7f5", + "reference": "95effeb9d6e2cec861cee06bf5bbf82d09aea7f5", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-18T13:12:43+00:00" + }, + { + "name": "symfony/serializer", + "version": "v6.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "76af774da9daf606d6400f1445b69d23efa3b238" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/76af774da9daf606d6400f1445b69d23efa3b238", + "reference": "76af774da9daf606d6400f1445b69d23efa3b238", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/dependency-injection": "<5.4", + "symfony/property-access": "<5.4", + "symfony/property-info": "<5.4", + "symfony/uid": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12", + "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/form": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "symfony/validator": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0", + "symfony/var-exporter": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/var-exporter": "For using the metadata compiler.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/serializer/tree/v6.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-12T05:10:31+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-30T19:18:58+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/266636bb8f3fbdccc302491df7b3a1b9a8c238a7", + "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-28T16:00:52+00:00" + }, + { + "name": "symfony/string", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "823f143370880efcbdfa2dbca946b3358c4707e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/823f143370880efcbdfa2dbca946b3358c4707e5", + "reference": "823f143370880efcbdfa2dbca946b3358c4707e5", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-10T09:34:31+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "e6cd330e5a072518f88d65148f3f165541807494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/e6cd330e5a072518f88d65148f3f165541807494", + "reference": "e6cd330e5a072518f88d65148f3f165541807494", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-07T08:04:03+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T17:24:16+00:00" + }, + { + "name": "symfony/uid", + "version": "v6.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "e03519f7b1ce1d3c0b74f751892bb41d549a2d98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/e03519f7b1ce1d3c0b74f751892bb41d549a2d98", + "reference": "e03519f7b1ce1d3c0b74f751892bb41d549a2d98", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v6.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-09-09T09:34:27+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "0f0adde127f24548e23cbde83bcaeadc491c551f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0f0adde127f24548e23cbde83bcaeadc491c551f", + "reference": "0f0adde127f24548e23cbde83bcaeadc491c551f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-07T08:04:03+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.1.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "66c6b0cf52b00f74614a2cf7ae7db08ea1095931" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/66c6b0cf52b00f74614a2cf7ae7db08ea1095931", + "reference": "66c6b0cf52b00f74614a2cf7ae7db08ea1095931", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.1.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-07T08:04:03+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.5", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5" + }, + "time": "2022-09-12T13:28:28+00:00" + }, + { + "name": "torann/geoip", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/Torann/laravel-geoip.git", + "reference": "3d730ae7470b86ae828b4128b1757a96156fd941" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Torann/laravel-geoip/zipball/3d730ae7470b86ae828b4128b1757a96156fd941", + "reference": "3d730ae7470b86ae828b4128b1757a96156fd941", + "shasum": "" + }, + "require": { + "illuminate/cache": "^8.0|^9.0", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^8.0" + }, + "require-dev": { + "geoip2/geoip2": "~2.1", + "mockery/mockery": "^1.3", + "phpstan/phpstan": "^0.12.14", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.5", + "vlucas/phpdotenv": "^5.0" + }, + "suggest": { + "geoip2/geoip2": "Required to use the MaxMind database or web service with GeoIP (~2.1).", + "monolog/monolog": "Allows for storing location not found errors to the log" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Torann\\GeoIP\\GeoIPServiceProvider" + ], + "aliases": { + "GeoIP": "Torann\\GeoIP\\Facades\\GeoIP" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Torann\\GeoIP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Daniel Stainback", + "email": "torann@gmail.com" + } + ], + "description": "Support for multiple GeoIP services.", + "keywords": [ + "IP API", + "geoip", + "geolocation", + "infoDB", + "laravel", + "location", + "maxmind" + ], + "support": { + "issues": "https://github.com/Torann/laravel-geoip/issues", + "source": "https://github.com/Torann/laravel-geoip/tree/3.0.4" + }, + "time": "2022-02-09T14:48:24+00:00" + }, + { + "name": "treeware/plant", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/TreewareEarth/plant.git", + "reference": "72414a6a0ff8c9c522a12842ebc153939323ae9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TreewareEarth/plant/zipball/72414a6a0ff8c9c522a12842ebc153939323ae9c", + "reference": "72414a6a0ff8c9c522a12842ebc153939323ae9c", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0" + }, + "require-dev": { + "composer/composer": "^1.0|^2.0", + "pestphp/pest": "^1.0", + "phpstan/phpstan": "^0.12", + "spatie/pest-plugin-snapshots": "^1.0", + "symfony/console": "^5.1", + "symplify/easy-coding-standard": "^9.2" + }, + "default-branch": true, + "type": "composer-plugin", + "extra": { + "class": "Treeware\\Plant\\Plugin" + }, + "autoload": { + "psr-4": { + "Treeware\\Plant\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "support": { + "issues": "https://github.com/TreewareEarth/plant/issues", + "source": "https://github.com/TreewareEarth/plant/tree/main" + }, + "time": "2021-05-04T19:10:49+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.5.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.5-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2022-10-16T01:01:54+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b56450eed252f6801410d810c8e1727224ae0743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-03-08T17:03:00+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "zbateson/mail-mime-parser", + "version": "2.2.3", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mail-mime-parser.git", + "reference": "295c7f82a8c44af685680d9df6714beb812e90ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/295c7f82a8c44af685680d9df6714beb812e90ff", + "reference": "295c7f82a8c44af685680d9df6714beb812e90ff", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7.0|^2.0", + "php": ">=5.4", + "pimple/pimple": "^3.0", + "zbateson/mb-wrapper": "^1.0.1", + "zbateson/stream-decorators": "^1.0.6" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6.0", + "sanmai/phpunit-legacy-adapter": "^6.3 || ^8.2" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MailMimeParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + }, + { + "name": "Contributors", + "homepage": "https://github.com/zbateson/mail-mime-parser/graphs/contributors" + } + ], + "description": "MIME email message parser", + "homepage": "https://mail-mime-parser.org", + "keywords": [ + "MimeMailParser", + "email", + "mail", + "mailparse", + "mime", + "mimeparse", + "parser", + "php-imap" + ], + "support": { + "docs": "https://mail-mime-parser.org/#usage-guide", + "issues": "https://github.com/zbateson/mail-mime-parser/issues", + "source": "https://github.com/zbateson/mail-mime-parser" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2022-09-28T16:31:49+00:00" + }, + { + "name": "zbateson/mb-wrapper", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mb-wrapper.git", + "reference": "5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a", + "reference": "5d9d190ef18ce6d424e3ac6f5ebe13901f92b74a", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "symfony/polyfill-iconv": "^1.9", + "symfony/polyfill-mbstring": "^1.9" + }, + "require-dev": { + "sanmai/phpunit-legacy-adapter": "^6.3 || ^8" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MbWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "Wrapper for mbstring with fallback to iconv for encoding conversion and string manipulation", + "keywords": [ + "charset", + "encoding", + "http", + "iconv", + "mail", + "mb", + "mb_convert_encoding", + "mbstring", + "mime", + "multibyte", + "string" + ], + "support": { + "issues": "https://github.com/zbateson/mb-wrapper/issues", + "source": "https://github.com/zbateson/mb-wrapper/tree/1.1.2" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2022-05-26T15:55:05+00:00" + }, + { + "name": "zbateson/stream-decorators", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/zbateson/stream-decorators.git", + "reference": "8f8ca208572963258b7e6d91106181706deacd10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/8f8ca208572963258b7e6d91106181706deacd10", + "reference": "8f8ca208572963258b7e6d91106181706deacd10", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7.0|^2.0", + "php": ">=5.4", + "zbateson/mb-wrapper": "^1.0.0" + }, + "require-dev": { + "sanmai/phpunit-legacy-adapter": "^6.3 || ^8" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\StreamDecorators\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "PHP psr7 stream decorators for mime message part streams", + "keywords": [ + "base64", + "charset", + "decorators", + "mail", + "mime", + "psr7", + "quoted-printable", + "stream", + "uuencode" + ], + "support": { + "issues": "https://github.com/zbateson/stream-decorators/issues", + "source": "https://github.com/zbateson/stream-decorators/tree/1.0.7" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2022-09-08T15:44:55+00:00" + }, + { + "name": "zendesk/zendesk_api_client_php", + "version": "v2.2.15", + "source": { + "type": "git", + "url": "https://github.com/zendesk/zendesk_api_client_php.git", + "reference": "d1da1a7f1548dc5218e864cdf213532b0768d8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendesk/zendesk_api_client_php/zipball/d1da1a7f1548dc5218e864cdf213532b0768d8c1", + "reference": "d1da1a7f1548dc5218e864cdf213532b0768d8c1", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0 || ^7.0", + "guzzlehttp/psr7": "^1.7 || ^2.0", + "mmucklo/inflect": "0.3.*", + "php": ">=5.5.0" + }, + "require-dev": { + "fzaninotto/faker": ">=1.5.0", + "phpmd/phpmd": "@stable", + "phpunit/phpunit": "4.5.*", + "psy/psysh": "@stable", + "squizlabs/php_codesniffer": "2.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "Zendesk\\API\\": "src/", + "Zendesk\\Console\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "PHP Client for Zendesk REST API. See https://developer.zendesk.com/rest_api/docs/core/introduction .", + "homepage": "https://github.com/zendesk/zendesk_api_client_php", + "support": { + "issues": "https://github.com/zendesk/zendesk_api_client_php/issues", + "source": "https://github.com/zendesk/zendesk_api_client_php/tree/v2.2.15" + }, + "time": "2022-06-20T05:20:31+00:00" + } + ], + "packages-dev": [ + { + "name": "barryvdh/laravel-debugbar", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-debugbar.git", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/3372ed65e6d2039d663ed19aa699956f9d346271", + "reference": "3372ed65e6d2039d663ed19aa699956f9d346271", + "shasum": "" + }, + "require": { + "illuminate/routing": "^7|^8|^9", + "illuminate/session": "^7|^8|^9", + "illuminate/support": "^7|^8|^9", + "maximebf/debugbar": "^1.17.2", + "php": ">=7.2.5", + "symfony/finder": "^5|^6" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "orchestra/testbench-dusk": "^5|^6|^7", + "phpunit/phpunit": "^8.5|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.6-dev" + }, + "laravel": { + "providers": [ + "Barryvdh\\Debugbar\\ServiceProvider" + ], + "aliases": { + "Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Barryvdh\\Debugbar\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "PHP Debugbar integration for Laravel", + "keywords": [ + "debug", + "debugbar", + "laravel", + "profiler", + "webprofiler" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-debugbar/issues", + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-07-11T09:26:42+00:00" + }, + { + "name": "laravel/dusk", + "version": "v6.25.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/dusk.git", + "reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/dusk/zipball/25a595ac3dc82089a91af10dd23b0d58fd3f6d0b", + "reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-zip": "*", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "nesbot/carbon": "^2.0", + "php": "^7.2|^8.0", + "php-webdriver/webdriver": "^1.9.0", + "symfony/console": "^4.3|^5.0|^6.0", + "symfony/finder": "^4.3|^5.0|^6.0", + "symfony/process": "^4.3|^5.0|^6.0", + "vlucas/phpdotenv": "^3.0|^4.0|^5.2" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.16|^5.17.1|^6.12.1|^7.0", + "phpunit/phpunit": "^7.5.15|^8.4|^9.0" + }, + "suggest": { + "ext-pcntl": "Used to gracefully terminate Dusk when tests are running." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Dusk\\DuskServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Dusk\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Dusk provides simple end-to-end testing and browser automation.", + "keywords": [ + "laravel", + "testing", + "webdriver" + ], + "support": { + "issues": "https://github.com/laravel/dusk/issues", + "source": "https://github.com/laravel/dusk/tree/v6.25.2" + }, + "time": "2022-09-29T09:37:07+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.16.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "0dbee8802e17911afbe29a8506316343829b056e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/0dbee8802e17911afbe29a8506316343829b056e", + "reference": "0dbee8802e17911afbe29a8506316343829b056e", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0", + "illuminate/contracts": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2022-11-21T16:19:18+00:00" + }, + { + "name": "maximebf/debugbar", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/maximebf/php-debugbar.git", + "reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/ba0af68dd4316834701ecb30a00ce9604ced3ee9", + "reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9", + "shasum": "" + }, + "require": { + "php": "^7.1|^8", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^2.6|^3|^4|^5|^6" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "twig/twig": "^1.38|^2.7|^3.0" + }, + "suggest": { + "kriswallsmith/assetic": "The best way to manage assets", + "monolog/monolog": "Log using Monolog", + "predis/predis": "Redis storage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + } + }, + "autoload": { + "psr-4": { + "DebugBar\\": "src/DebugBar/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maxime Bouroumeau-Fuseau", + "email": "maxime.bouroumeau@gmail.com", + "homepage": "http://maximebf.com" + }, + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Debug bar in the browser for php application", + "homepage": "https://github.com/maximebf/php-debugbar", + "keywords": [ + "debug", + "debugbar" + ], + "support": { + "issues": "https://github.com/maximebf/php-debugbar/issues", + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.1" + }, + "time": "2022-03-31T14:55:54+00:00" + }, + { + "name": "php-webdriver/webdriver", + "version": "1.13.1", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c", + "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^5.6 || ~7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "ondram/ci-detector": "^2.1 || ^3.5 || ^4.0", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^1.1 || ^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0" + }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Exception/TimeoutException.php" + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", + "homepage": "https://github.com/php-webdriver/php-webdriver", + "keywords": [ + "Chromedriver", + "geckodriver", + "php", + "selenium", + "webdriver" + ], + "support": { + "issues": "https://github.com/php-webdriver/php-webdriver/issues", + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.13.1" + }, + "time": "2022-10-11T11:49:44+00:00" + }, + { + "name": "spatie/flare-client-php", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/flare-client-php.git", + "reference": "ebb9ae0509b75e02f128b39537eb9a3ef5ce18e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/ebb9ae0509b75e02f128b39537eb9a3ef5ce18e8", + "reference": "ebb9ae0509b75e02f128b39537eb9a3ef5ce18e8", + "shasum": "" + }, + "require": { + "illuminate/pipeline": "^8.0|^9.0", + "php": "^8.0", + "spatie/backtrace": "^1.2", + "symfony/http-foundation": "^5.0|^6.0", + "symfony/mime": "^5.2|^6.0", + "symfony/process": "^5.2|^6.0", + "symfony/var-dumper": "^5.2|^6.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.3.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/phpunit-snapshot-assertions": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\FlareClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Send PHP errors to Flare", + "homepage": "https://github.com/spatie/flare-client-php", + "keywords": [ + "exception", + "flare", + "reporting", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/flare-client-php/issues", + "source": "https://github.com/spatie/flare-client-php/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-11-16T08:30:20+00:00" + }, + { + "name": "spatie/ignition", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ignition.git", + "reference": "dd3d456779108d7078baf4e43f8c2b937d9794a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ignition/zipball/dd3d456779108d7078baf4e43f8c2b937d9794a1", + "reference": "dd3d456779108d7078baf4e43f8c2b937d9794a1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "monolog/monolog": "^2.0", + "php": "^8.0", + "spatie/flare-client-php": "^1.1", + "symfony/console": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "symfony/process": "^5.4|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\Ignition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for PHP applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/ignition/issues", + "source": "https://github.com/spatie/ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-08-26T11:51:15+00:00" + }, + { + "name": "spatie/laravel-ignition", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ignition.git", + "reference": "2b79cf6ed40946b64ac6713d7d2da8a9d87f612b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/2b79cf6ed40946b64ac6713d7d2da8a9d87f612b", + "reference": "2b79cf6ed40946b64ac6713d7d2da8a9d87f612b", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/support": "^8.77|^9.27", + "monolog/monolog": "^2.3", + "php": "^8.0", + "spatie/flare-client-php": "^1.0.1", + "spatie/ignition": "^1.4.1", + "symfony/console": "^5.0|^6.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "filp/whoops": "^2.14", + "livewire/livewire": "^2.8|dev-develop", + "mockery/mockery": "^1.4", + "nunomaduro/larastan": "^1.0", + "orchestra/testbench": "^6.23|^7.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-ray": "^1.27" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ], + "aliases": { + "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\LaravelIgnition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for Laravel applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/laravel-ignition/issues", + "source": "https://github.com/spatie/laravel-ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-10-26T17:39:54+00:00" + }, + { + "name": "timacdonald/log-fake", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/timacdonald/log-fake.git", + "reference": "0abb5782c66e3ec01df46ed2062b31900fdb743a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/timacdonald/log-fake/zipball/0abb5782c66e3ec01df46ed2062b31900fdb743a", + "reference": "0abb5782c66e3ec01df46ed2062b31900fdb743a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/collections": "^9.0", + "illuminate/contracts": "^9.0", + "illuminate/log": "^9.0", + "illuminate/support": "^9.0", + "php": "^8.0", + "phpunit/phpunit": "^9.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "illuminate/config": "^9.0", + "illuminate/container": "^9.0", + "symfony/var-dumper": "^6.0", + "timacdonald/callable-fake": "^1.5" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump and dd function (^6.0)." + }, + "type": "library", + "autoload": { + "psr-4": { + "TiMacDonald\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tim MacDonald", + "email": "hello@timacdonald.me", + "homepage": "https://timacdonald.me" + } + ], + "description": "A drop in fake logger for testing with the Laravel framework.", + "keywords": [ + "fake", + "laravel", + "log", + "logger", + "testing" + ], + "support": { + "docs": "https://github.com/timacdonald/log-fake/blob/master/readme.md", + "issues": "https://github.com/timacdonald/log-fake/issues", + "source": "https://github.com/timacdonald/log-fake/releases/latest" + }, + "time": "2022-05-08T07:06:45+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config/activitylog.php b/config/activitylog.php new file mode 100644 index 0000000..77d473d --- /dev/null +++ b/config/activitylog.php @@ -0,0 +1,54 @@ + env('ACTIVITY_LOGGER_ENABLED', true), + + /* + * When the clean-command is executed, all recording activities older than + * the number of days specified here will be deleted. + */ + 'delete_records_older_than_days' => 365, + + /* + * If no log name is passed to the activity() helper + * we use this default log name. + */ + 'default_log_name' => 'default', + + /* + * You can specify an auth driver here that gets user models. + * If this is null we'll use the default Laravel auth driver. + */ + 'default_auth_driver' => null, + + /* + * If set to true, the subject returns soft deleted models. + */ + 'subject_returns_soft_deleted_models' => false, + + /* + * This model will be used to log activity. + * It should be implements the Spatie\Activitylog\Contracts\Activity interface + * and extend Illuminate\Database\Eloquent\Model. + */ + 'activity_model' => \Domain\Status\Models\Activity::class, + + /* + * This is the name of the table that will be created by the migration and + * used by the Activity model shipped with this package. + */ + 'table_name' => 'activity_log', + + /* + * This is the database connection that will be used by the migration and + * the Activity model shipped with this package. In case it's not set + * Laravel database.default will be used instead. + */ + 'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'), +]; diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..6fe6d06 --- /dev/null +++ b/config/app.php @@ -0,0 +1,264 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | your application so that it is used when running Artisan tasks. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + 'asset_url' => env('ASSET_URL', null), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. We have gone + | ahead and set this to a sensible default for you out of the box. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is used by the Illuminate encrypter service and should be set + | to a random, 32 character string, otherwise these encrypted strings + | will not be safe. Please do this before deploying an application! + | + */ + + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + /* + * Laravel Framework Service Providers... + */ + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + + /* + * Application Service Providers... + */ + App\Providers\AppServiceProvider::class, + App\Providers\AuthServiceProvider::class, + // App\Providers\BroadcastServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\HorizonServiceProvider::class, + App\Providers\LivewireServiceProvider::class, + App\Providers\RouteServiceProvider::class, + App\Providers\ViewServiceProvider::class, + ARKEcosystem\Foundation\Providers\TelescopeServiceProvider::class, + + ], + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. However, feel free to register as many as you wish as + | the aliases are "lazy" loaded so they don't hinder performance. + | + */ + + 'aliases' => [ + + 'App' => Illuminate\Support\Facades\App::class, + 'Arr' => Illuminate\Support\Arr::class, + 'Artisan' => Illuminate\Support\Facades\Artisan::class, + 'Auth' => Illuminate\Support\Facades\Auth::class, + 'Blade' => Illuminate\Support\Facades\Blade::class, + 'Broadcast' => Illuminate\Support\Facades\Broadcast::class, + 'Bus' => Illuminate\Support\Facades\Bus::class, + 'Cache' => Illuminate\Support\Facades\Cache::class, + 'Config' => Illuminate\Support\Facades\Config::class, + 'Cookie' => Illuminate\Support\Facades\Cookie::class, + 'Crypt' => Illuminate\Support\Facades\Crypt::class, + 'DB' => Illuminate\Support\Facades\DB::class, + 'Eloquent' => Illuminate\Database\Eloquent\Model::class, + 'Event' => Illuminate\Support\Facades\Event::class, + 'File' => Illuminate\Support\Facades\File::class, + 'Gate' => Illuminate\Support\Facades\Gate::class, + 'Hash' => Illuminate\Support\Facades\Hash::class, + 'Lang' => Illuminate\Support\Facades\Lang::class, + 'Log' => Illuminate\Support\Facades\Log::class, + 'Mail' => Illuminate\Support\Facades\Mail::class, + 'Notification' => Illuminate\Support\Facades\Notification::class, + 'Password' => Illuminate\Support\Facades\Password::class, + 'Queue' => Illuminate\Support\Facades\Queue::class, + 'Redirect' => Illuminate\Support\Facades\Redirect::class, + 'Redis' => Illuminate\Support\Facades\Redis::class, + 'Request' => Illuminate\Support\Facades\Request::class, + 'Response' => Illuminate\Support\Facades\Response::class, + 'Route' => Illuminate\Support\Facades\Route::class, + 'Schema' => Illuminate\Support\Facades\Schema::class, + 'Session' => Illuminate\Support\Facades\Session::class, + 'Storage' => Illuminate\Support\Facades\Storage::class, + 'Str' => Illuminate\Support\Str::class, + 'URL' => Illuminate\Support\Facades\URL::class, + 'Validator' => Illuminate\Support\Facades\Validator::class, + 'View' => Illuminate\Support\Facades\View::class, + + // Aliases for quick access in blade + 'ActivityDescriptionEnum' => ActivityDescriptionEnum::class, + 'AddressPrefixes' => AddressPrefixes::class, + 'Carbon' => Carbon::class, + 'NotificationFilterEnum' => NotificationFilterEnum::class, + 'DateFormat' => DateFormat::class, + 'Format' => Format::class, + 'NotificationBuilder' => NotificationBuilder::class, + 'PresetTypeEnum' => PresetTypeEnum::class, + 'ServerAttributeEnum' => ServerAttributeEnum::class, + 'ServerProviderTypeEnum' => ServerProviderTypeEnum::class, + 'TokenAttributeEnum' => TokenAttributeEnum::class, + 'User' => User::class, + 'NetworkTypeEnum' => NetworkTypeEnum::class, + 'TokenInvitationController' => TokenInvitationController::class, + 'LeaveTeamModal' => LeaveTeamModal::class, + 'Visitor' => ARKEcosystem\Foundation\Support\Facades\Visitor::class, + 'ServerDeploymentStatus' => Domain\Server\Enums\ServerDeploymentStatus::class, + ], +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..c3c554c --- /dev/null +++ b/config/auth.php @@ -0,0 +1,119 @@ + [ + 'guard' => 'web', + 'passwords' => 'users', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session", "token" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + + 'api' => [ + 'driver' => 'token', + 'provider' => 'users', + 'hash' => false, + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => Domain\User\Models\User::class, + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expire time is the number of minutes that the reset token should be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_resets', + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => 10800, + +]; diff --git a/config/aws.php b/config/aws.php new file mode 100644 index 0000000..2e582ff --- /dev/null +++ b/config/aws.php @@ -0,0 +1,25 @@ + env('AWS_REGION', 'us-east-1'), + 'version' => 'latest', + 'imageIds' => [ + 'ubuntu-18-04-lts' => 'ami-04b9e92b5572fa0d1', + ], +]; diff --git a/config/backup.php b/config/backup.php new file mode 100644 index 0000000..70c681c --- /dev/null +++ b/config/backup.php @@ -0,0 +1,233 @@ + [ + + /* + * The name of this application. You can use this name to monitor + * the backups. + */ + 'name' => env('APP_NAME', 'laravel-backup'), + + 'source' => [ + + 'files' => [ + + /* + * The list of directories and files that will be included in the backup. + */ + 'include' => [ + base_path(), + ], + + /* + * These directories and files will be excluded from the backup. + * + * Directories used by the backup process will automatically be excluded. + */ + 'exclude' => [ + base_path('vendor'), + base_path('node_modules'), + ], + + /* + * Determines if symlinks should be followed. + */ + 'follow_links' => false, + ], + + /* + * The names of the connections to the databases that should be backed up + * MySQL, PostgreSQL, SQLite and Mongo databases are supported. + * + * The content of the database dump may be customized for each connection + * by adding a 'dump' key to the connection settings in config/database.php. + * E.g. + * 'mysql' => [ + * ... + * 'dump' => [ + * 'excludeTables' => [ + * 'table_to_exclude_from_backup', + * 'another_table_to_exclude' + * ] + * ], + * ], + * + * If you are using only InnoDB tables on a MySQL server, you can + * also supply the useSingleTransaction option to avoid table locking. + * + * E.g. + * 'mysql' => [ + * ... + * 'dump' => [ + * 'useSingleTransaction' => true, + * ], + * ], + * + * For a complete list of available customization options, see https://github.com/spatie/db-dumper + */ + 'databases' => [ + env('DB_CONNECTION', 'pgsql'), + ], + ], + + /* + * The database dump can be compressed to decrease diskspace usage. + * + * Out of the box Laravel-backup supplies + * Spatie\DbDumper\Compressors\GzipCompressor::class. + * + * You can also create custom compressor. More info on that here: + * https://github.com/spatie/db-dumper#using-compression + * + * If you do not want any compressor at all, set it to null. + */ + 'database_dump_compressor' => null, + + 'destination' => [ + + /* + * The filename prefix used for the backup zip file. + */ + 'filename_prefix' => '', + + /* + * The disk names on which the backups will be stored. + */ + 'disks' => [ + 'local', + ], + ], + + /* + * The directory where the temporary files will be stored. + */ + 'temporary_directory' => storage_path('app/backup-temp'), + ], + + /* + * You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'. + * For Slack you need to install guzzlehttp/guzzle and laravel/slack-notification-channel. + * + * You can also use your own notification classes, just make sure the class is named after one of + * the `Spatie\Backup\Events` classes. + */ + 'notifications' => [ + + 'notifications' => [ + \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class => ['mail'], + \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class => ['mail'], + ], + + /* + * Here you can specify the notifiable to which the notifications should be sent. The default + * notifiable will use the variables specified in this config file. + */ + 'notifiable' => \Spatie\Backup\Notifications\Notifiable::class, + + 'mail' => [ + 'to' => 'your@example.com', + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + ], + + 'slack' => [ + 'webhook_url' => '', + + /* + * If this is set to null the default channel of the webhook will be used. + */ + 'channel' => null, + + 'username' => null, + + 'icon' => null, + + ], + ], + + /* + * Here you can specify which backups should be monitored. + * If a backup does not meet the specified requirements the + * UnHealthyBackupWasFound event will be fired. + */ + 'monitor_backups' => [ + [ + 'name' => env('APP_NAME', 'laravel-backup'), + 'disks' => ['local'], + 'health_checks' => [ + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, + ], + ], + + /* + [ + 'name' => 'name of the second app', + 'disks' => ['local', 's3'], + 'health_checks' => [ + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumAgeInDays::class => 1, + \Spatie\Backup\Tasks\Monitor\HealthChecks\MaximumStorageInMegabytes::class => 5000, + ], + ], + */ + ], + + 'cleanup' => [ + /* + * The strategy that will be used to cleanup old backups. The default strategy + * will keep all backups for a certain amount of days. After that period only + * a daily backup will be kept. After that period only weekly backups will + * be kept and so on. + * + * No matter how you configure it the default strategy will never + * delete the newest backup. + */ + 'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class, + + 'default_strategy' => [ + + /* + * The number of days for which backups must be kept. + */ + 'keep_all_backups_for_days' => 7, + + /* + * The number of days for which daily backups must be kept. + */ + 'keep_daily_backups_for_days' => 16, + + /* + * The number of weeks for which one weekly backup must be kept. + */ + 'keep_weekly_backups_for_weeks' => 8, + + /* + * The number of months for which one monthly backup must be kept. + */ + 'keep_monthly_backups_for_months' => 4, + + /* + * The number of years for which one yearly backup must be kept. + */ + 'keep_yearly_backups_for_years' => 2, + + /* + * After cleaning up the backups remove the oldest backup until + * this amount of megabytes has been reached. + */ + 'delete_oldest_backups_when_using_more_megabytes_than' => 5000, + ], + ], + +]; diff --git a/config/blade-icons.php b/config/blade-icons.php new file mode 100644 index 0000000..8ec4678 --- /dev/null +++ b/config/blade-icons.php @@ -0,0 +1,198 @@ + [ + + 'default' => [ + + /* + |----------------------------------------------------------------- + | Icons Path + |----------------------------------------------------------------- + | + | Provide the relative path from your app root to your SVG icons + | directory. Icons are loaded recursively so there's no need to + | list every sub-directory. + | + | Relative to the disk root when the disk option is set. + | + */ + + 'path' => 'vendor/arkecosystem/foundation/resources/assets/icons', + + /* + |----------------------------------------------------------------- + | Filesystem Disk + |----------------------------------------------------------------- + | + | Optionally, provide a specific filesystem disk to read + | icons from. When defining a disk, the "path" option + | starts relatively from the disk root. + | + */ + + 'disk' => '', + + /* + |----------------------------------------------------------------- + | Default Prefix + |----------------------------------------------------------------- + | + | This config option allows you to define a default prefix for + | your icons. The dash separator will be applied automatically + | to every icon name. It's required and needs to be unique. + | + */ + + 'prefix' => 'icon', + + /* + |----------------------------------------------------------------- + | Fallback Icon + |----------------------------------------------------------------- + | + | This config option allows you to define a fallback + | icon when an icon in this set cannot be found. + | + */ + + 'fallback' => 'question-mark-small', + + /* + |----------------------------------------------------------------- + | Default Set Classes + |----------------------------------------------------------------- + | + | This config option allows you to define some classes which + | will be applied by default to all icons within this set. + | + */ + + 'class' => 'fill-current', + + /* + |----------------------------------------------------------------- + | Default Set Attributes + |----------------------------------------------------------------- + | + | This config option allows you to define some attributes which + | will be applied by default to all icons within this set. + | + */ + + 'attributes' => [ + // 'width' => 50, + // 'height' => 50, + ], + + ], + + 'app' => [ + 'path' => 'resources/icons', + 'prefix' => 'app', + 'class' => '', + 'fallback' => 'question-mark-small', + ], + + 'fortify' => [ + 'path' => 'vendor/arkecosystem/foundation/resources/images', + 'prefix' => 'fortify', + 'class' => '', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global Default Classes + |-------------------------------------------------------------------------- + | + | This config option allows you to define some classes which + | will be applied by default to all icons. + | + */ + + 'class' => '', + + /* + |-------------------------------------------------------------------------- + | Global Default Attributes + |-------------------------------------------------------------------------- + | + | This config option allows you to define some attributes which + | will be applied by default to all icons. + | + */ + + 'attributes' => [ + // 'width' => 50, + // 'height' => 50, + ], + + /* + |-------------------------------------------------------------------------- + | Global Fallback Icon + |-------------------------------------------------------------------------- + | + | This config option allows you to define a global fallback + | icon when an icon in any set cannot be found. It can + | reference any icon from any configured set. + | + */ + + 'fallback' => '', + + /* + |-------------------------------------------------------------------------- + | Components + |-------------------------------------------------------------------------- + | + | These config options allow you to define some + | settings related to Blade Components. + | + */ + + 'components' => [ + + /* + |---------------------------------------------------------------------- + | Disable Components + |---------------------------------------------------------------------- + | + | This config option allows you to disable Blade components + | completely. It's useful to avoid performance problems + | when working with large icon libraries. + | + */ + + 'disabled' => false, + + /* + |---------------------------------------------------------------------- + | Default Icon Component Name + |---------------------------------------------------------------------- + | + | This config option allows you to define the name + | for the default Icon class component. + | + */ + + 'default' => 'icon', + + ], + +]; diff --git a/config/broadcasting.php b/config/broadcasting.php new file mode 100644 index 0000000..47d6d1c --- /dev/null +++ b/config/broadcasting.php @@ -0,0 +1,57 @@ + env('BROADCAST_DRIVER', 'null'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_APP_KEY'), + 'secret' => env('PUSHER_APP_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + 'options' => [ + 'cluster' => env('PUSHER_APP_CLUSTER'), + 'useTLS' => true, + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + 'null' => [ + 'driver' => 'null', + ], + ], +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..cb45512 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,106 @@ + env('CACHE_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'cache', + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), + +]; diff --git a/config/cors.php b/config/cors.php new file mode 100644 index 0000000..733c51c --- /dev/null +++ b/config/cors.php @@ -0,0 +1,36 @@ + ['api/*'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => false, + + 'max_age' => false, + + 'supports_credentials' => false, + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..162f070 --- /dev/null +++ b/config/database.php @@ -0,0 +1,143 @@ + env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DATABASE_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_DB', 0), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => env('REDIS_CACHE_DB', 1), + ], + ], +]; diff --git a/config/debugbar.php b/config/debugbar.php new file mode 100644 index 0000000..cf77ad3 --- /dev/null +++ b/config/debugbar.php @@ -0,0 +1,204 @@ + env('DEBUGBAR_ENABLED', null), + 'except' => [ + 'telescope*', + ], + + /* + |-------------------------------------------------------------------------- + | Storage settings + |-------------------------------------------------------------------------- + | + | DebugBar stores data for session/ajax requests. + | You can disable this, so the debugbar stores data in headers/session, + | but this can cause problems with large data collectors. + | By default, file storage (in the storage folder) is used. Redis and PDO + | can also be used. For PDO, run the package migrations first. + | + */ + 'storage' => [ + 'enabled' => true, + 'driver' => 'file', // redis, file, pdo, custom + 'path' => storage_path('debugbar'), // For file driver + 'connection' => null, // Leave null for default connection (Redis/PDO) + 'provider' => '', // Instance of StorageInterface for custom driver + ], + + /* + |-------------------------------------------------------------------------- + | Vendors + |-------------------------------------------------------------------------- + | + | Vendor files are included by default, but can be set to false. + | This can also be set to 'js' or 'css', to only include javascript or css vendor files. + | Vendor files are for css: font-awesome (including fonts) and highlight.js (css files) + | and for js: jquery and and highlight.js + | So if you want syntax highlighting, set it to true. + | jQuery is set to not conflict with existing jQuery scripts. + | + */ + + 'include_vendors' => true, + + /* + |-------------------------------------------------------------------------- + | Capture Ajax Requests + |-------------------------------------------------------------------------- + | + | The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors), + | you can use this option to disable sending the data through the headers. + | + | Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools. + */ + + 'capture_ajax' => true, + 'add_ajax_timing' => false, + + /* + |-------------------------------------------------------------------------- + | Custom Error Handler for Deprecated warnings + |-------------------------------------------------------------------------- + | + | When enabled, the Debugbar shows deprecated warnings for Symfony components + | in the Messages tab. + | + */ + 'error_handler' => false, + + /* + |-------------------------------------------------------------------------- + | Clockwork integration + |-------------------------------------------------------------------------- + | + | The Debugbar can emulate the Clockwork headers, so you can use the Chrome + | Extension, without the server-side code. It uses Debugbar collectors instead. + | + */ + 'clockwork' => false, + + /* + |-------------------------------------------------------------------------- + | DataCollectors + |-------------------------------------------------------------------------- + | + | Enable/disable DataCollectors + | + */ + + 'collectors' => [ + 'phpinfo' => true, // Php version + 'messages' => true, // Messages + 'time' => true, // Time Datalogger + 'memory' => true, // Memory usage + 'exceptions' => false, // Exception displayer + 'log' => true, // Logs from Monolog (merged in messages if enabled) + 'db' => true, // Show database (PDO) queries and bindings + 'views' => true, // Views with their data + 'route' => false, // Current route information + 'auth' => false, // Display Laravel authentication status + 'gate' => true, // Display Laravel Gate checks + 'session' => true, // Display session data + 'symfony_request' => true, // Only one can be enabled.. + 'mail' => true, // Catch mail messages + 'laravel' => true, // Laravel version and environment + 'events' => false, // All events fired + 'default_request' => false, // Regular or special Symfony request logger + 'logs' => true, // Add the latest log messages + 'files' => false, // Show the included files + 'config' => false, // Display config settings + 'cache' => true, // Display cache events + 'models' => true, // Display models + ], + + /* + |-------------------------------------------------------------------------- + | Extra options + |-------------------------------------------------------------------------- + | + | Configure some DataCollectors + | + */ + + 'options' => [ + 'auth' => [ + 'show_name' => true, // Also show the users name/email in the debugbar + ], + 'db' => [ + 'with_params' => true, // Render SQL with the parameters substituted + 'backtrace' => true, // Use a backtrace to find the origin of the query in your files. + 'timeline' => true, // Add the queries to the timeline + 'explain' => [ // Show EXPLAIN output on queries + 'enabled' => false, + 'types' => ['SELECT'], // // workaround ['SELECT'] only. https://github.com/barryvdh/laravel-debugbar/issues/888 ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+ + ], + 'hints' => true, // Show hints for common mistakes + ], + 'mail' => [ + 'full_log' => false, + ], + 'views' => [ + 'data' => false, //Note: Can slow down the application, because the data can be quite large.. + ], + 'route' => [ + 'label' => true, // show complete route on bar + ], + 'logs' => [ + 'file' => null, + ], + 'cache' => [ + 'values' => true, // collect cache values + ], + ], + + /* + |-------------------------------------------------------------------------- + | Inject Debugbar in Response + |-------------------------------------------------------------------------- + | + | Usually, the debugbar is added just before , by listening to the + | Response after the App is done. If you disable this, you have to add them + | in your template yourself. See http://phpdebugbar.com/docs/rendering.html + | + */ + + 'inject' => true, + + /* + |-------------------------------------------------------------------------- + | DebugBar route prefix + |-------------------------------------------------------------------------- + | + | Sometimes you want to set route prefix to be used by DebugBar to load + | its resources from. Usually the need comes from misconfigured web server or + | from trying to overcome bugs like this: http://trac.nginx.org/nginx/ticket/97 + | + */ + 'route_prefix' => '_debugbar', + + /* + |-------------------------------------------------------------------------- + | DebugBar route domain + |-------------------------------------------------------------------------- + | + | By default DebugBar route served from the same domain that request served. + | To override default domain, specify it as a non-empty value. + */ + 'route_domain' => null, +]; diff --git a/config/deployer.php b/config/deployer.php new file mode 100644 index 0000000..b4fb133 --- /dev/null +++ b/config/deployer.php @@ -0,0 +1,46 @@ + [ + 'length' => env('OPENSSH_KEY_LENGTH', 4096), + 'name' => env('OPENSSH_KEY_NAME', 'ark-deployer-temporary-key'), + ], + 'branch' => env('DEPLOYER_BRANCH', 'master'), + + /* + |-------------------------------------------------------------------------- + | Deployment Options + |-------------------------------------------------------------------------- + */ + 'deployment' => [ + 'minimumServerRam' => env('DEPLOYMENT_GENESIS_MIN_RAM', 2048), + 'minimumCores' => env('DEPLOYMENT_EXPLORER_MIN_CPU', 2), + ], + + /* + |-------------------------------------------------------------------------- + | Supported Server Providers + |-------------------------------------------------------------------------- + */ + 'server_providers' => [ + App\Enums\ServerProviderTypeEnum::DIGITALOCEAN => true, + App\Enums\ServerProviderTypeEnum::HETZNER => true, + // App\Enums\ServerProviderTypeEnum::VULTR => false, + // App\Enums\ServerProviderTypeEnum::AWS => false, + ], + + /* + |-------------------------------------------------------------------------- + | Wheter or not show the cookie consent pop up + |-------------------------------------------------------------------------- + */ + 'enable_cookieconsent' => env('ENABLE_COOKIECONSENT', true), +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..678d11b --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,111 @@ + env('FILESYSTEM_DRIVER', 'local'), + + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ + + 'cloud' => env('FILESYSTEM_CLOUD', 's3'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + | Supported Drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + ], + + 'media' => [ + 'driver' => 'local', + 'root' => public_path('media'), + ], + + 'token-config' => [ + 'driver' => 'local', + 'root' => storage_path('token-config'), + ], + + 'personal-data-exports' => [ + 'driver' => 'local', + 'root' => storage_path('app/personal-data-exports'), + ], + + // Livewire added a temporary file upload disk configuration. + // See https://github.com/livewire/livewire/pull/2571 + // But even with this configuration applied, we got an error. + // The solution is to set the test disk used by Livewire with the default disk. + // See https://github.com/livewire/livewire/issues/1341 + 'tmp-for-tests' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/config/fortify.php b/config/fortify.php new file mode 100644 index 0000000..0f38f8b --- /dev/null +++ b/config/fortify.php @@ -0,0 +1,133 @@ + 'web', + + /* + |-------------------------------------------------------------------------- + | Fortify Password Broker + |-------------------------------------------------------------------------- + | + | Here you may specify which password broker Fortify can use when a user + | is resetting their password. This configured value should match one + | of your password brokers setup in your "auth" configuration file. + | + */ + + 'passwords' => 'users', + + /* + |-------------------------------------------------------------------------- + | Username / Email + |-------------------------------------------------------------------------- + | + | This value defines which model attribute should be considered as your + | application's "username" field. Typically, this might be the email + | address of the users but you are free to change this value here. + | + | Out of the box, Fortify expects forgot password and reset password + | requests to have a field named 'email'. If the application uses + | another name for the field you may define it below as needed. + | + */ + + 'username' => 'email', + + 'username_alt' => null, + + 'email' => 'email', + + /* + |-------------------------------------------------------------------------- + | Home Path + |-------------------------------------------------------------------------- + | + | Here you may configure the path where users will get redirected during + | authentication or password reset when the operations are successful + | and the user is authenticated. You are free to change this value. + | + */ + + 'home' => RouteServiceProvider::HOME, + + /* + |-------------------------------------------------------------------------- + | Fortify Routes Middleware + |-------------------------------------------------------------------------- + | + | Here you may specify which middleware Fortify will assign to the routes + | that it registers with the application. If necessary, you may change + | these middleware but typically this provided default is preferred. + | + */ + + 'middleware' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Rate Limiting + |-------------------------------------------------------------------------- + | + | By default, Fortify will throttle logins to five requests per minute for + | every email and IP address combination. However, if you would like to + | specify a custom rate limiter to call then you may specify it here. + | + */ + + 'limiters' => [ + 'login' => null, + ], + + /* + |-------------------------------------------------------------------------- + | Features + |-------------------------------------------------------------------------- + | + | Some of the Fortify features are optional. You may disable the features + | by removing them from this array. You're free to only remove some of + | these features or you can even remove all of these if you need to. + | + */ + + 'features' => [ + Features::registration(), + Features::resetPasswords(), + Features::emailVerification(), + Features::updateProfileInformation(), + Features::updatePasswords(), + Features::twoFactorAuthentication([ + 'confirmPassword' => true, + ]), + ], + + /* + |-------------------------------------------------------------------------- + | Models + |-------------------------------------------------------------------------- + */ + + 'models' => [ + 'user' => User::class, + 'invitation' => Invitation::class, + ], + +]; diff --git a/config/github.php b/config/github.php new file mode 100644 index 0000000..b968e7d --- /dev/null +++ b/config/github.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +return [ + /* + |-------------------------------------------------------------------------- + | Default Connection Name + |-------------------------------------------------------------------------- + | + | Here you may specify which of the connections below you wish to use as + | your default connection for all work. Of course, you may use many + | connections at once using the manager class. + | + */ + + 'default' => 'app', + + /* + |-------------------------------------------------------------------------- + | GitHub Connections + |-------------------------------------------------------------------------- + | + | Here are each of the connections setup for your application. Example + | configuration has been included, but you may add as many connections as + | you would like. Note that the 5 supported authentication methods are: + | "application", "jwt", "none", "password", and "token". + | + */ + + 'connections' => [ + 'main' => [ + 'token' => 'your-token', + 'method' => 'token', + // 'backoff' => false, + // 'cache' => false, + // 'version' => 'v3', + // 'enterprise' => false, + ], + + 'jwt' => [ + 'token' => 'your-jwt-token', + 'method' => 'jwt', + // 'backoff' => false, + // 'cache' => false, + // 'version' => 'v3', + // 'enterprise' => false, + ], + + 'other' => [ + 'username' => 'your-username', + 'password' => 'your-password', + 'method' => 'password', + // 'backoff' => false, + // 'cache' => false, + // 'version' => 'v3', + // 'enterprise' => false, + ], + + 'none' => [ + 'method' => 'none', + // 'backoff' => false, + // 'cache' => false, + // 'version' => 'v3', + // 'enterprise' => false, + ], + + 'private' => [ + 'appId' => 'your-github-app-id', + 'keyPath' => 'your-private-key-path', + 'method' => 'private', + // 'backoff' => false, + // 'cache' => false, + // 'version' => 'v3', + // 'enterprise' => false, + ], + ], +]; diff --git a/config/google2fa.php b/config/google2fa.php new file mode 100644 index 0000000..f2ddad2 --- /dev/null +++ b/config/google2fa.php @@ -0,0 +1,81 @@ + true, + + /* + * Lifetime in minutes. + * + * In case you need your users to be asked for a new one time passwords from time to time. + */ + 'lifetime' => 0, // 0 = eternal + + /* + * Renew lifetime at every new request. + */ + 'keep_alive' => true, + + /* + * Auth container binding. + */ + 'auth' => 'auth', + + /* + * 2FA verified session var. + */ + + 'session_var' => 'google2fa', + + /* + * One Time Password request input name. + */ + 'otp_input' => 'one_time_password', + + /* + * One Time Password Window. + */ + 'window' => 1, + + /* + * Forbid user to reuse One Time Passwords. + */ + 'forbid_old_passwords' => false, + + /* + * User's table column for google2fa secret. + */ + 'otp_secret_column' => 'google2fa_secret', + + /* + * One Time Password View. + */ + 'view' => 'google2fa.index', + + /* + * One Time Password error message. + */ + 'error_messages' => [ + 'wrong_otp' => "The 'One Time Password' typed was wrong.", + 'cannot_be_empty' => 'One Time Password cannot be empty.', + 'unknown' => 'An unknown error has occurred. Please try again.', + ], + + /* + * Throw exceptions or just fire events? + */ + 'throw_exceptions' => true, + + /* + * Which image backend to use for generating QR codes? + * + * Supports imagemagick, svg and eps + */ + 'qrcode_image_backend' => \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_SVG, + +]; diff --git a/config/hashing.php b/config/hashing.php new file mode 100644 index 0000000..7b49806 --- /dev/null +++ b/config/hashing.php @@ -0,0 +1,52 @@ + 'bcrypt', + + /* + |-------------------------------------------------------------------------- + | Bcrypt Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Bcrypt algorithm. This will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'bcrypt' => [ + 'rounds' => env('BCRYPT_ROUNDS', 10), + ], + + /* + |-------------------------------------------------------------------------- + | Argon Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Argon algorithm. These will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'argon' => [ + 'memory' => 1024, + 'threads' => 2, + 'time' => 2, + ], +]; diff --git a/config/hermes.php b/config/hermes.php new file mode 100644 index 0000000..8ae7194 --- /dev/null +++ b/config/hermes.php @@ -0,0 +1,15 @@ + [ + + 'notification' => DatabaseNotification::class, + + ], + +]; diff --git a/config/horizon.php b/config/horizon.php new file mode 100644 index 0000000..6f5e46c --- /dev/null +++ b/config/horizon.php @@ -0,0 +1,181 @@ + null, + + /* + |-------------------------------------------------------------------------- + | Horizon Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Horizon will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => 'horizon', + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Connection + |-------------------------------------------------------------------------- + | + | This is the name of the Redis connection where Horizon will store the + | meta information required for it to function. It includes the list + | of supervisors, failed jobs, job metrics, and other information. + | + */ + + 'use' => 'default', + + /* + |-------------------------------------------------------------------------- + | Horizon Redis Prefix + |-------------------------------------------------------------------------- + | + | This prefix will be used when storing all Horizon data in Redis. You + | may modify the prefix when you are running multiple installations + | of Horizon on the same server so that they don't have problems. + | + */ + + 'prefix' => env('HORIZON_PREFIX', 'horizon:'), + + /* + |-------------------------------------------------------------------------- + | Horizon Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will get attached onto each Horizon route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Queue Wait Time Thresholds + |-------------------------------------------------------------------------- + | + | This option allows you to configure when the LongWaitDetected event + | will be fired. Every connection / queue combination may have its + | own, unique threshold (in seconds) before this event is fired. + | + */ + + 'waits' => [ + 'redis:default' => 60, + ], + + /* + |-------------------------------------------------------------------------- + | Job Trimming Times + |-------------------------------------------------------------------------- + | + | Here you can configure for how long (in minutes) you desire Horizon to + | persist the recent and failed jobs. Typically, recent jobs are kept + | for one hour while all failed jobs are stored for an entire week. + | + */ + + 'trim' => [ + 'recent' => 60, + 'recent_failed' => 10080, + 'failed' => 10080, + 'monitored' => 10080, + ], + + /* + |-------------------------------------------------------------------------- + | Fast Termination + |-------------------------------------------------------------------------- + | + | When this option is enabled, Horizon's "terminate" command will not + | wait on all of the workers to terminate unless the --wait option + | is provided. Fast termination can shorten deployment delay by + | allowing a new instance of Horizon to start while the last + | instance will continue to terminate each of its workers. + | + */ + + 'fast_termination' => false, + + /* + |-------------------------------------------------------------------------- + | Memory Limit (MB) + |-------------------------------------------------------------------------- + | + | This value describes the maximum amount of memory the Horizon worker + | may consume before it is terminated and restarted. You should set + | this value according to the resources available to your server. + | + */ + + 'memory_limit' => 64, + + /* + |-------------------------------------------------------------------------- + | Queue Worker Configuration + |-------------------------------------------------------------------------- + | + | Here you may define the queue worker settings used by your application + | in all environments. These supervisors and settings handle all your + | queued jobs and will be provisioned by Horizon during deployment. + | + */ + + 'environments' => [ + 'production' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'simple', + 'processes' => 10, + 'tries' => 5, + ], + 'supervisor-long-running' => [ + 'connection' => 'redis-long-running', + 'queue' => ['long-running-queue'], + 'balance' => 'simple', + 'processes' => 10, + 'tries' => 5, + 'timeout' => 3600, + ], + ], + + 'local' => [ + 'supervisor-1' => [ + 'connection' => 'redis', + 'queue' => ['default'], + 'balance' => 'simple', + 'processes' => 10, + 'tries' => 5, + ], + 'supervisor-long-running' => [ + 'connection' => 'redis-long-running', + 'queue' => ['long-running-queue'], + 'balance' => 'simple', + 'processes' => 10, + 'tries' => 5, + 'timeout' => 3600, + ], + ], + ], +]; diff --git a/config/livewire.php b/config/livewire.php new file mode 100644 index 0000000..e87e17a --- /dev/null +++ b/config/livewire.php @@ -0,0 +1,160 @@ + 'App\\Http\\Livewire', + + /* + |-------------------------------------------------------------------------- + | View Path + |-------------------------------------------------------------------------- + | + | This value sets the path for Livewire component views. This affects + | file manipulation helper commands like `artisan make:livewire`. + | + */ + + 'view_path' => resource_path('views/livewire'), + + /* + |-------------------------------------------------------------------------- + | Layout + |-------------------------------------------------------------------------- + | The default layout view that will be used when rendering a component via + | Route::get('/some-endpoint', SomeComponent::class);. In this case the + | the view returned by SomeComponent will be wrapped in "layouts.app" + | + */ + + 'layout' => 'layouts.app', + + /* + |-------------------------------------------------------------------------- + | Livewire Assets URL + |-------------------------------------------------------------------------- + | + | This value sets the path to Livewire JavaScript assets, for cases where + | your app's domain root is not the correct path. By default, Livewire + | will load its JavaScript assets from the app's "relative root". + | + | Examples: "/assets", "myurl.com/app". + | + */ + + 'asset_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire App URL + |-------------------------------------------------------------------------- + | + | This value should be used if livewire assets are served from CDN. + | Livewire will communicate with an app through this url. + | + | Examples: "https://my-app.com", "myurl.com/app". + | + */ + + 'app_url' => null, + + /* + |-------------------------------------------------------------------------- + | Livewire Endpoint Middleware Group + |-------------------------------------------------------------------------- + | + | This value sets the middleware group that will be applied to the main + | Livewire "message" endpoint (the endpoint that gets hit everytime + | a Livewire component updates). It is set to "web" by default. + | + */ + + 'middleware_group' => 'web', + + /* + |-------------------------------------------------------------------------- + | Livewire Temporary File Uploads Endpoint Configuration + |-------------------------------------------------------------------------- + | + | Livewire handles file uploads by storing uploads in a temporary directory + | before the file is validated and stored permanently. All file uploads + | are directed to a global endpoint for temporary storage. The config + | items below are used for customizing the way the endpoint works. + | + */ + + 'temporary_file_upload' => [ + 'disk' => null, // Example: 'local', 's3' Default: 'default' + 'rules' => null, // Example: ['file', 'mimes:png,jpg'] Default: ['required', 'file', 'max:12288'] (12MB) + 'directory' => null, // Example: 'tmp' Default 'livewire-tmp' + 'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1' + 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs. + 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', + 'mov', 'avi', 'wmv', 'mp3', 'm4a', + 'jpg', 'jpeg', 'mpga', 'webp', 'wma', + ], + 'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated. + ], + + /* + |-------------------------------------------------------------------------- + | Manifest File Path + |-------------------------------------------------------------------------- + | + | This value sets the path to the Livewire manifest file. + | The default should work for most cases (which is + | "/bootstrap/cache/livewire-components.php"), but for specific + | cases like when hosting on Laravel Vapor, it could be set to a different value. + | + | Example: for Laravel Vapor, it would be "/tmp/storage/bootstrap/cache/livewire-components.php". + | + */ + + 'manifest_path' => null, + + /* + |-------------------------------------------------------------------------- + | Back Button Cache + |-------------------------------------------------------------------------- + | + | This value determines whether the back button cache will be used on pages + | that contain Livewire. By disabling back button cache, it ensures that + | the back button shows the correct state of components, instead of + | potentially stale, cached data. + | + | Setting it to "false" (default) will disable back button cache. + | + */ + + 'back_button_cache' => false, + + /* + |-------------------------------------------------------------------------- + | Render On Redirect + |-------------------------------------------------------------------------- + | + | This value determines whether Livewire will render before it's redirected + | or not. Setting it to "false" (default) will mean the render method is + | skipped when redirecting. And "true" will mean the render method is + | run before redirecting. Browsers bfcache can store a potentially + | stale view if render is skipped on redirect. + | + */ + + 'render_on_redirect' => true, + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..ee24948 --- /dev/null +++ b/config/logging.php @@ -0,0 +1,94 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", + | "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['daily'], + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => 'debug', + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => 'debug', + 'days' => 14, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => 'Laravel Log', + 'emoji' => ':boom:', + 'level' => 'critical', + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => 'debug', + 'handler' => SyslogUdpHandler::class, + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + ], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => 'debug', + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => 'debug', + ], + ], +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..ac9f822 --- /dev/null +++ b/config/mail.php @@ -0,0 +1,113 @@ + env('MAIL_MAILER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers to be used while + | sending an e-mail. You will specify which one you are using for your + | mailers below. You are free to add additional mailers as required. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", + | "postmark", "log", "array" + | + */ + + 'mailers' => [ + 'smtp' => [ + 'transport' => 'smtp', + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + 'port' => env('MAIL_PORT', 587), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => '/usr/sbin/sendmail -bs', + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + + /* + |-------------------------------------------------------------------------- + | Markdown Mail Settings + |-------------------------------------------------------------------------- + | + | If you are using Markdown based email rendering, you may configure your + | theme and component paths here, allowing you to customize the design + | of the emails. Or, you may simply stick with the Laravel defaults! + | + */ + + 'markdown' => [ + 'theme' => 'default', + + 'paths' => [ + resource_path('views/vendor/mail'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Stub Address that acts as catch-all + |-------------------------------------------------------------------------- + */ + + 'stub' => [ + 'address' => env('MAIL_TO_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_TO_NAME', 'Example'), + ], + +]; diff --git a/config/model-status.php b/config/model-status.php new file mode 100644 index 0000000..fd4f56a --- /dev/null +++ b/config/model-status.php @@ -0,0 +1,20 @@ + Domain\Status\Models\Status::class, + + /* + * The name of the column which holds the ID of the model related to the statuses. + * + * You can change this value if you have set a different name in the migration for the statuses table. + */ + 'model_primary_key_attribute' => 'model_id', +]; diff --git a/config/personal-data-export.php b/config/personal-data-export.php new file mode 100644 index 0000000..47b525e --- /dev/null +++ b/config/personal-data-export.php @@ -0,0 +1,36 @@ + 'personal-data-exports', + + /* + * The amount of days the exports will be available. + */ + 'delete_after_days' => 5, + + /* + * Determines whether the user should be logged in to be able + * to access the export. + */ + 'authentication_required' => true, + + /* + * The notification which will be sent to the user when the export + * has been created. + */ + 'notification' => \App\User\Mail\PersonalDataExport::class, + + /* + * Configure the queue and connection used by `CreatePersonalDataExportJob` + * which will create the export. + */ + 'job' => [ + 'queue' => null, + 'connection' => null, + ], +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..e9bda44 --- /dev/null +++ b/config/queue.php @@ -0,0 +1,99 @@ + env('QUEUE_CONNECTION', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'retry_after' => 90, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'retry_after' => 90, + 'block_for' => 0, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'your-queue-name'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => 90, + 'block_for' => null, + ], + + 'redis-long-running' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => 3600, + 'block_for' => null, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/responsecache.php b/config/responsecache.php new file mode 100644 index 0000000..ead809c --- /dev/null +++ b/config/responsecache.php @@ -0,0 +1,73 @@ + env('RESPONSE_CACHE_ENABLED', false), + + /* + * The given class will determinate if a request should be cached. The + * default class will cache all successful GET-requests. + * + * You can provide your own class given that it implements the + * CacheProfile interface. + */ + 'cache_profile' => Spatie\ResponseCache\CacheProfiles\CacheAllSuccessfulGetRequests::class, + + /* + * When using the default CacheRequestFilter this setting controls the + * default number of seconds responses must be cached. + */ + 'cache_lifetime_in_seconds' => env('RESPONSE_CACHE_LIFETIME', 60 * 60 * 24 * 7), + + /* + * This setting determines if a http header named with the cache time + * should be added to a cached response. This can be handy when + * debugging. + */ + 'add_cache_time_header' => env('APP_DEBUG', true), + + /* + * This setting determines the name of the http header that contains + * the time at which the response was cached + */ + 'cache_time_header_name' => env('RESPONSE_CACHE_HEADER_NAME', 'oc-responsecache'), + + /* + * Here you may define the cache store that should be used to store + * requests. This can be the name of any store that is + * configured in app/config/cache.php + */ + 'cache_store' => env('RESPONSE_CACHE_DRIVER', 'file'), + + /* + * Here you may define replacers that dynamically replace content from the response. + * Each replacer must implement the Replacer interface. + */ + 'replacers' => [ + \Spatie\ResponseCache\Replacers\CsrfTokenReplacer::class, + ], + + /* + * If the cache driver you configured supports tags, you may specify a tag name + * here. All responses will be tagged. When clearing the responsecache only + * items with that tag will be flushed. + * + * You may use a string or an array here. + */ + 'cache_tag' => '', + + /* + * This class is responsible for generating a hash for a request. This hash + * is used to look up an cached response. + */ + 'hasher' => \Spatie\ResponseCache\Hasher\DefaultHasher::class, + + /* + * This class is responsible for serializing responses. + */ + 'serializer' => \Spatie\ResponseCache\Serializers\DefaultSerializer::class, +]; diff --git a/config/sentry.php b/config/sentry.php new file mode 100644 index 0000000..5b22f29 --- /dev/null +++ b/config/sentry.php @@ -0,0 +1,15 @@ + env('SENTRY_LARAVEL_DSN', env('SENTRY_DSN')), + + // capture release as git sha + // 'release' => trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')), + + 'breadcrumbs' => [ + // Capture bindings on SQL queries logged in breadcrumbs + 'sql_bindings' => true, + ], +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..6046e9f --- /dev/null +++ b/config/services.php @@ -0,0 +1,39 @@ + [ + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + ], + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'recaptcha' => [ + 'site' => env('RECAPTCHA_SITE'), + 'secret' => env('RECAPTCHA_SECRET'), + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..715dd82 --- /dev/null +++ b/config/session.php @@ -0,0 +1,199 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION', null), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc", "memcached", or "dynamodb" session drivers you may + | list a cache store that should be used for these sessions. This value + | must match with one of the application's configured cache "stores". + | + */ + + 'store' => env('SESSION_STORE', null), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', null), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | do not enable this as other CSRF protection services are in place. + | + | Supported: "lax", "strict" + | + */ + + 'same_site' => 'lax', +]; diff --git a/config/social.php b/config/social.php new file mode 100644 index 0000000..ede3c53 --- /dev/null +++ b/config/social.php @@ -0,0 +1,17 @@ + [ + 'twitter' => [ + 'icon' => 'brands.solid.twitter', + 'url' => 'https://twitter.com/Ardent_HQ', + ], + + 'github' => [ + 'icon' => 'brands.solid.github', + 'url' => 'https://github.com/ArdentHQ', + ], + ], +]; diff --git a/config/telescope.php b/config/telescope.php new file mode 100644 index 0000000..3c00d2a --- /dev/null +++ b/config/telescope.php @@ -0,0 +1,154 @@ + null, + + /* + |-------------------------------------------------------------------------- + | Telescope Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Telescope will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => 'telescope', + + /* + |-------------------------------------------------------------------------- + | Telescope Storage Driver + |-------------------------------------------------------------------------- + | + | This configuration options determines the storage driver that will + | be used to store Telescope's data. In addition, you may set any + | custom options as needed by the particular driver you choose. + | + */ + + 'driver' => env('TELESCOPE_DRIVER', 'database'), + + 'storage' => [ + 'database' => [ + 'connection' => env('DB_CONNECTION', 'mysql'), + ], + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Master Switch + |-------------------------------------------------------------------------- + | + | This option may be used to disable all Telescope watchers regardless + | of their individual configuration, which simply provides a single + | and convenient way to enable or disable Telescope data storage. + | + */ + + 'enabled' => env('TELESCOPE_ENABLED', true), + + /* + |-------------------------------------------------------------------------- + | Telescope Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will be assigned to every Telescope route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ], + + /* + |-------------------------------------------------------------------------- + | Ignored Paths & Commands + |-------------------------------------------------------------------------- + | + | The following array lists the URI paths and Artisan commands that will + | not be watched by Telescope. In addition to this list, some Laravel + | commands, like migrations and queue commands, are always ignored. + | + */ + + 'ignore_paths' => [ + ], + + 'ignore_commands' => [ + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Watchers + |-------------------------------------------------------------------------- + | + | The following array lists the "watchers" that will be registered with + | Telescope. The watchers gather the application's profile data when + | a request or task is executed. Feel free to customize this list. + | + */ + + 'watchers' => [ + Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true), + + Watchers\CommandWatcher::class => [ + 'enabled' => env('TELESCOPE_COMMAND_WATCHER', true), + 'ignore' => [], + ], + + Watchers\DumpWatcher::class => env('TELESCOPE_DUMP_WATCHER', true), + Watchers\EventWatcher::class => env('TELESCOPE_EVENT_WATCHER', true), + Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true), + Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true), + Watchers\LogWatcher::class => env('TELESCOPE_LOG_WATCHER', true), + Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true), + + Watchers\ModelWatcher::class => [ + 'enabled' => env('TELESCOPE_MODEL_WATCHER', true), + 'events' => ['eloquent.*'], + ], + + Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true), + + Watchers\QueryWatcher::class => [ + 'enabled' => env('TELESCOPE_QUERY_WATCHER', true), + 'ignore_packages' => true, + 'slow' => 100, + ], + + Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true), + + Watchers\RequestWatcher::class => [ + 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true), + 'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64), + ], + + Watchers\GateWatcher::class => [ + 'enabled' => env('TELESCOPE_GATE_WATCHER', true), + 'ignore_abilities' => [], + 'ignore_packages' => true, + ], + + Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true), + ], +]; diff --git a/config/tracking.php b/config/tracking.php new file mode 100644 index 0000000..b796a64 --- /dev/null +++ b/config/tracking.php @@ -0,0 +1,10 @@ + [ + 'key' => env('GOOGLE_ANALYTICS_TRACKING_KEY'), + 'domain' => env('GOOGLE_ANALYTICS_COOKIE_DOMAIN'), + ], +]; diff --git a/config/trustedproxy.php b/config/trustedproxy.php new file mode 100644 index 0000000..6772ca1 --- /dev/null +++ b/config/trustedproxy.php @@ -0,0 +1,8 @@ + env('APP_ENV', 'production') === 'local' ? '*' : [], +]; diff --git a/config/view.php b/config/view.php new file mode 100644 index 0000000..548125a --- /dev/null +++ b/config/view.php @@ -0,0 +1,51 @@ + [ + resource_path('views'), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => env( + 'VIEW_COMPILED_PATH', + realpath(storage_path('framework/views')) + ), + + /* + |-------------------------------------------------------------------------- + | Blade View Modification Checking + |-------------------------------------------------------------------------- + | + | On every request the framework will check to see if a view has expired + | to determine if it needs to be recompiled. If you are in production + | and precompiling views this feature may be disabled to save time. + | + */ + + 'expires' => env('VIEW_CHECK_EXPIRATION', true), + +]; diff --git a/config/web.php b/config/web.php new file mode 100644 index 0000000..ce1e514 --- /dev/null +++ b/config/web.php @@ -0,0 +1,23 @@ + [ + 'source' => 'ARKLauncher', + 'subjects' => [ + [ + 'label' => 'General', + 'value' => 'general', + ], + [ + 'label' => 'Bug Report', + 'value' => 'bug_report', + ], + [ + 'label' => 'Other', + 'value' => 'other', + ], + ], + ], +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..97fc976 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1,2 @@ +*.sqlite +*.sqlite-journal diff --git a/database/factories/CoinFactory.php b/database/factories/CoinFactory.php new file mode 100644 index 0000000..f5d5d46 --- /dev/null +++ b/database/factories/CoinFactory.php @@ -0,0 +1,32 @@ + 'ARK', + 'slug' => 'ark', + 'symbol' => 'ARK', + ]; + } +} diff --git a/database/factories/DatabaseNotificationFactory.php b/database/factories/DatabaseNotificationFactory.php new file mode 100644 index 0000000..3bc523d --- /dev/null +++ b/database/factories/DatabaseNotificationFactory.php @@ -0,0 +1,47 @@ + $this->faker->uuid(), + 'type' => "App\TestNotification", + 'notifiable_type' => User::class, + 'notifiable_id' => $this->token ? $this->token->user->id : 1, + 'data' => [ + 'relatable_type' => $this->token ? $this->token->getMorphClass() : null, + 'relatable_id' => $this->token ? $this->token->getKey() : null, + 'token' => $this->token ? $this->token->id : 1, + 'content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', + 'type' => 'success', + 'action' => [ + 'title' => 'View', + 'url' => route('home'), + ], + ], + ]; + } + + public function ownedBy(Token $token) + { + $this->token = $token; + + return $this; + } +} diff --git a/database/factories/InvitationFactory.php b/database/factories/InvitationFactory.php new file mode 100644 index 0000000..55a7216 --- /dev/null +++ b/database/factories/InvitationFactory.php @@ -0,0 +1,43 @@ + $this->faker->uuid(), + 'token_id' => Token::factory(), + 'user_id' => User::factory(), + 'email' => $this->faker->email(), + 'role' => 'collaborator', + 'permissions' => $this->faker->randomElements( + $permissions, + $this->faker->numberBetween(1, count($permissions)) + ), + ]; + } +} diff --git a/database/factories/NetworkFactory.php b/database/factories/NetworkFactory.php new file mode 100644 index 0000000..7f7d622 --- /dev/null +++ b/database/factories/NetworkFactory.php @@ -0,0 +1,50 @@ + $this->token ?? Token::factory(), + 'name' => 'mainnet', + ]; + } + + public function ownedBy(Token $token) + { + $this->token = $token; + + return $this; + } + + public function createForTest() + { + $network = $this->create(['token_id' => $this->token ?? Token::factory()]); + + return Network::findOrFail($network->id); + } +} diff --git a/database/factories/SecureShellKeyFactory.php b/database/factories/SecureShellKeyFactory.php new file mode 100644 index 0000000..c36d0d8 --- /dev/null +++ b/database/factories/SecureShellKeyFactory.php @@ -0,0 +1,52 @@ + $this->faker->firstName(), + 'user_id' => $this->user ?? User::factory(), + 'public_key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCYAi5XvpgT1tBUFVwD4fc+XigWVKUkBx0OhbGbxfm918TmarQy4LDKtX3Xqjm6ownmVE97E1Gvc5sIln6hwk+mtkXqQMrdD8tNqtYIr2mwW5yJDON0ml8mhn1Kb5myRkdFX+B411c3OJrsIv7t1OUAsAx+mrX4wanHENOnhHRhuiXP08OkXXpwQYPItmNWwyokcZ9etI6eP9SMlyrdneZTCZWsf++Gv4zh+XTdchiaYfiquAmtFwYnC3VinUwMuZPWhvYHL7Loo9sYTPpoW1YR/wyIhM33nd3yOnIPVODp8mn/VjjYRLPjYkhzOejOlP2W3MVkSY2SX156X5Rm7XDsggq0gWEHZ01lYhvWzO3gfUNjUH+3PDKNJcl+pOEjSHCsIKSFfTxV6cMkUhKFx2b0Gw8Q2msToZSFnzczyLXPA6r+9DMS0X78buBh+JXOevXaV2nWGrOvEmSyQBMLVb9EeRrmFnOwoxubIc7BDQpKJT3Pd62s+pWkSJrc/gegHCQzxZ8ZZZfwACTezm7u333MiuAf/VEUMMTUCyGjNmbPGtqIhDbQvRokxsEz0jNYuCy8OpsOZDLHn20lEw7nIXVe17YAV4ByvDXKqKNnX9fd6AsgSQlyF7VpGWN2dGZ9CpNVkHpy29skTWzKwLGGD+SmIspBec5lxZz+HaFWZDra1Q== robot@ark.io', + // 'public_key' => ShellSecureShellKey::make()['publicKey'], + ]; + } + + public function ownedBy(User $user) + { + $this->user = $user; + + return $this; + } + + public function createForTest($overrides = []) + { + $secureShellKey = $this->create( + array_merge($overrides, ['user_id' => $this->user ?? User::factory()]) + ); + + return SecureShellKey::findOrFail($secureShellKey->id); + } +} diff --git a/database/factories/ServerFactory.php b/database/factories/ServerFactory.php new file mode 100644 index 0000000..967bb45 --- /dev/null +++ b/database/factories/ServerFactory.php @@ -0,0 +1,133 @@ + Network::factory(), + 'server_provider_id' => ServerProvider::factory(), + 'name' => Str::slug($this->faker->name()), + 'provider_server_id' => mt_rand(1000000, 9999999), + 'server_provider_plan_id' => ServerProviderPlan::factory(), + 'server_provider_region_id' => ServerProviderRegion::factory(), + 'server_provider_image_id' => ServerProviderImage::factory(), + 'ip_address' => $this->faker->ipv4(), + 'user_password' => $this->faker->password(), + 'sudo_password' => $this->faker->password(), + 'delegate_passphrase' => $this->faker->password(), + 'delegate_password' => $this->faker->password(), + 'preset' => 'relay', + ]; + } + + public function hetzner() + { + return $this->state([ + 'server_provider_id' => ServerProvider::factory()->hetzner(), + ]); + } + + public function digitalocean() + { + return $this->state([ + 'server_provider_id' => ServerProvider::factory()->digitalocean(), + ]); + } + + public function vultr() + { + return $this->state([ + 'server_provider_id' => ServerProvider::factory()->vultr(), + ]); + } + + public function linode() + { + return $this->state([ + 'server_provider_id' => ServerProvider::factory()->linode(), + ]); + } + + public function aws() + { + return $this->state([ + 'server_provider_id' => ServerProvider::factory()->aws(), + ]); + } + + public function genesis() + { + return $this->state(['preset' => 'genesis']); + } + + public function seed() + { + return $this->state(['preset' => 'seed']); + } + + public function relay() + { + return $this->state(['preset' => 'relay']); + } + + public function forger() + { + return $this->state(['preset' => 'forger']); + } + + public function explorer() + { + return $this->state(['preset' => 'explorer']); + } + + public function ownedBy(Network $network) + { + $this->network = $network; + + return $this; + } + + public function createForTest(?array $attributes = []) + { + $server = $this->create([ + 'network_id' => $this->network ?? Network::factory(), + ] + $attributes); + + $server->setMetaAttribute(ServerAttributeEnum::CREATOR, $server->token->user->id); + + $server->token->shareWith($server->token->user, 'owner'); + + return Server::findOrFail($server->id); + } +} diff --git a/database/factories/ServerProviderFactory.php b/database/factories/ServerProviderFactory.php new file mode 100644 index 0000000..d544c9b --- /dev/null +++ b/database/factories/ServerProviderFactory.php @@ -0,0 +1,142 @@ + $this->token ?? Token::factory(), + 'type' => ServerProviderTypeEnum::DIGITALOCEAN, + 'name' => $this->faker->unique()->domainName(), + 'extra_attributes' => ['accessToken' => encrypt(Str::random(42))], + 'provider_key_id' => 512190, + ]; + } + + public function digitalocean() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::DIGITALOCEAN, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 512190, + ]); + } + + public function hetzner() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::HETZNER, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 2323, + ]); + } + + public function vultr() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::VULTR, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => '541b4960f23bd', + ]); + } + + public function linode() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::LINODE, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 1234, + ]); + } + + public function aws() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::AWS, + 'name' => $this->faker->unique()->domainName(), + 'extra_attributes' => [ + 'accessToken' => encrypt(Str::random(42)), + 'accessKey' => encrypt(Str::random(42)), + ], + ]); + } + + public function withRegions() + { + return $this->afterCreating(function (ServerProvider $serverProvider) { + $serverProvider->regions() + ->syncWithoutDetaching(ServerProviderRegion::factory()->count(3)->create()); + }); + } + + public function withImages() + { + return $this->afterCreating(function (ServerProvider $serverProvider) { + $serverProvider->images() + ->syncWithoutDetaching(ServerProviderImage::factory()->count(3)->create()); + }); + } + + public function withPlans() + { + return $this->afterCreating(function (ServerProvider $serverProvider) { + $override = [ + 'memory' => config('deployer.deployment.minimumServerRam') + 1, + ]; + if ($serverProvider->regions()->exists()) { + $override['regions'] = $serverProvider->regions()->pluck('uuid'); + } + $serverProvider->plans() + ->syncWithoutDetaching( + ServerProviderPlan::factory()->count(3)->create($override) + ); + }); + } + + public function ownedBy(Token $token) + { + $this->token = $token; + + return $this; + } + + public function createForTest(?array $attributes = []) + { + $serverProvider = $this->create([ + 'token_id' => $this->token ?? Token::factory(), + ] + $attributes); + + $serverProvider->token->shareWith($serverProvider->token->user, 'owner'); + + return ServerProvider::findOrFail($serverProvider->id); + } +} diff --git a/database/factories/ServerProviderImageFactory.php b/database/factories/ServerProviderImageFactory.php new file mode 100644 index 0000000..39e0b09 --- /dev/null +++ b/database/factories/ServerProviderImageFactory.php @@ -0,0 +1,83 @@ + $this->faker->uuid(), + 'name' => $this->faker->name(), + ]; + } + + public function digitalocean() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::DIGITALOCEAN, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 512190, + ]); + } + + public function hetzner() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::HETZNER, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 2323, + ]); + } + + public function vultr() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::VULTR, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => '541b4960f23bd', + ]); + } + + public function linode() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::LINODE, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 1234, + ]); + } + + public function aws() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::AWS, + 'name' => $this->faker->unique()->domainName(), + 'extra_attributes' => [ + 'accessToken' => encrypt(Str::random(42)), + 'accessKey' => encrypt(Str::random(42)), + ], + ]); + } +} diff --git a/database/factories/ServerProviderPlanFactory.php b/database/factories/ServerProviderPlanFactory.php new file mode 100644 index 0000000..767f28f --- /dev/null +++ b/database/factories/ServerProviderPlanFactory.php @@ -0,0 +1,91 @@ +faker->numberBetween(1, 8); + $memory = $this->faker->randomElement([2, 4, 8, 16, 32]); + + $uuid = (string) Str::uuid(); + + return [ + 'uuid' => "{$uuid}-{$cores}vpcu-{$memory}gb{$this->faker->randomElement(['-intel', '-amd', ''])}", + 'disk' => $this->faker->numberBetween(1, 1024), + 'memory' => $memory * 1024, + 'cores' => $cores, + 'regions' => $this->faker->words(), + ]; + } + + public function digitalocean() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::DIGITALOCEAN, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 512190, + ]); + } + + public function hetzner() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::HETZNER, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 2323, + ]); + } + + public function vultr() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::VULTR, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => '541b4960f23bd', + ]); + } + + public function linode() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::LINODE, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 1234, + ]); + } + + public function aws() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::AWS, + 'name' => $this->faker->unique()->domainName(), + 'extra_attributes' => [ + 'accessToken' => encrypt(Str::random(42)), + 'accessKey' => encrypt(Str::random(42)), + ], + ]); + } +} diff --git a/database/factories/ServerProviderRegionFactory.php b/database/factories/ServerProviderRegionFactory.php new file mode 100644 index 0000000..96977c6 --- /dev/null +++ b/database/factories/ServerProviderRegionFactory.php @@ -0,0 +1,83 @@ + $this->faker->uuid(), + 'name' => $this->faker->unique()->city(), + ]; + } + + public function digitalocean() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::DIGITALOCEAN, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 512190, + ]); + } + + public function hetzner() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::HETZNER, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 2323, + ]); + } + + public function vultr() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::VULTR, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => '541b4960f23bd', + ]); + } + + public function linode() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::LINODE, + 'name' => $this->faker->unique()->domainName(), + 'provider_key_id' => 1234, + ]); + } + + public function aws() + { + return $this->state([ + 'type' => ServerProviderTypeEnum::AWS, + 'name' => $this->faker->unique()->domainName(), + 'extra_attributes' => [ + 'accessToken' => encrypt(Str::random(42)), + 'accessKey' => encrypt(Str::random(42)), + ], + ]); + } +} diff --git a/database/factories/ServerTaskFactory.php b/database/factories/ServerTaskFactory.php new file mode 100644 index 0000000..309d7c8 --- /dev/null +++ b/database/factories/ServerTaskFactory.php @@ -0,0 +1,41 @@ + Server::factory(), + 'type' => ProvisionUser::class, + 'name' => $this->faker->firstName(), + 'user' => $this->faker->username(), + 'exit_code' => 0, + 'script' => $this->faker->word(), + 'output' => $this->faker->paragraph(), + 'options' => [], + ]; + } +} diff --git a/database/factories/TokenFactory.php b/database/factories/TokenFactory.php new file mode 100644 index 0000000..22ba139 --- /dev/null +++ b/database/factories/TokenFactory.php @@ -0,0 +1,297 @@ + [ + 'static' => [ + 'vote' => 100000000, + 'transfer' => 10000000, + 'multiSignature' => 500000000, + 'secondSignature' => 500000000, + 'delegateRegistration' => 2500000000, + 'ipfs' => 0, + 'multiPayment' => 0, + 'delegateResignation' => 2500000000, + ], + 'dynamic' => [ + 'enabled' => false, + 'addonBytes' => [ + 'ipfs' => 250, + 'vote' => 100, + 'transfer' => 100, + 'multiPayment' => 500, + 'multiSignature' => 500, + 'secondSignature' => 250, + 'delegateResignation' => 400000, + 'delegateRegistration' => 400000, + ], + 'minFeePool' => 3000, + 'minFeeBroadcast' => 3000, + ], + ], + 'token' => 'TST', + 'coreIp' => '127.0.0.1', + 'symbol' => 'TST', + 'apiPort' => 4003, + 'forgers' => 51, + 'p2pPort' => 4000, + 'blocktime' => 8, + 'chainName' => 'testing', + 'explorerIp' => '0.0.0.0', + 'devnetPeers' => [ + 0 => '0.0.0.0', + ], + 'webhookPort' => 4004, + 'monitorPort' => 4005, + 'databaseHost' => '1.1.1.1', + 'databaseName' => 'core_token', + 'databasePort' => '5432', + 'devnetPrefix' => 'D', + 'explorerPort' => 4200, + 'licenseEmail' => null, + 'mainnetPeers' => [ + 0 => '0.0.0.0', + ], + 'totalPremine' => 2100000000000000, + 'mainnetPrefix' => 'M', + 'testnetPrefix' => 'T', + 'rewardPerBlock' => 200000000, + 'rewardHeightStart' => 1, + 'vendorFieldLength' => 255, + 'transactionsPerBlock' => 150, + 'maxBlockPayload' => 2097152, + 'wif' => 1, + ]; + + protected $user; + + protected $status; + + private int $networkCount = 0; + + private int $serverCount = 1; + + private int $invitationsCount = 1; + + private int $serverProviderCount = 0; + + private bool $defaultNetworks = false; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'user_id' => User::factory(), + 'coin_id' => Coin::factory(), + 'name' => $this->faker->firstName(), + 'slug' => $this->faker->firstName(), + 'config' => $this->config, + 'keypair' => [ + 'privateKey' => encrypt($this->faker->word()), + 'publicKey' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQDDHr/jh2Jy4yALcK4JyWbVkPRaWmhck3IgCoeOO3z1e2dBowLh64QAM+Qb72pxekALga2oi4GvT+TlWNhzPH4V example', + ], + 'extra_attributes' => ['repoName' => $this->faker->firstName()], + ]; + } + + /** + * New token ready to be configured. + */ + public function newly(): Factory + { + $name = $this->faker->slug(3); + + return $this->state(fn () => [ + 'name' => $name, + 'slug' => $name, + 'config' => null, + 'keypair' => null, + 'onboarded_at' => null, + ])->afterCreating(function (Token $token) { + TokenCreated::dispatch($token); + }); + } + + /** + * Onboarding configuration completed. + */ + public function withOnboardingConfigurationCompleted(): Factory + { + $name = $this->faker->slug(3); + + return $this->state(fn () => [ + 'name' => $name, + 'slug' => $name, + ])->afterCreating(function (Token $token) { + TokenCreated::dispatch($token); + + $token->setMetaAttribute('onboarding.configuration_completed_at', Carbon::now()); + }); + } + + /** + * With Onboarding server provider select. + */ + public function withOnboardingServerProvider(): Factory + { + return $this->withOnboardingConfigurationCompleted()->afterCreating(function (Token $token) { + $token->setMetaAttribute('onboarding.server_providers_status', 'completed'); + + ServerProvider::factory() + ->withRegions() + ->withImages() + ->withPlans() + ->create(['token_id' => $token->id]); + }); + } + + /** + * Onboarding server configuration completed. + */ + public function withOnboardingServerConfiguration(): Factory + { + return $this->withOnboardingServerProvider()->afterCreating(function (Token $token) { + $token->setMetaAttribute(TokenAttributeEnum::SERVER_CONFIG, [ + 'server_provider_id' => 1, + ]); + }); + } + + /** + * Onboarding secure shell key completed. + */ + public function withOnboardingSecureShellKey(): Factory + { + return $this->withOnboardingServerConfiguration()->afterCreating(function (Token $token) { + $token->secureShellKeys()->sync(SecureShellKey::factory()->create()->id); + }); + } + + public function ownedBy(User $user) + { + $this->user = $user; + + return $this; + } + + public function withNetwork(int $count): self + { + $this->networkCount = $count; + + return $this; + } + + public function withDefaultNetworks(): self + { + $this->defaultNetworks = true; + + return $this; + } + + public function withServerProviders(int $count): self + { + $this->serverProviderCount = $count; + + return $this; + } + + public function withServers(int $count): self + { + $this->serverCount = $count; + + return $this; + } + + public function withInvitations(int $count): self + { + $this->invitationsCount = $count; + + return $this; + } + + public function withStatus(string $status): self + { + $this->status = $status; + + return $this; + } + + public function createForTest(?array $attributes = []) + { + $user = $this->user ?? User::withoutEvents(function () { + return User::factory()->create(); + }); + + $coin = Coin::withoutEvents(function () { + return Coin::factory()->create(); + }); + + $token = $this->create([ + 'user_id' => $user->id, + 'coin_id' => $coin->id, + ] + $attributes); + + // Share the token with the owner + $token->shareWith($user, 'owner'); + + if ($this->status) { + $token->setStatus($this->status); + } + + if ($this->serverProviderCount > 0) { + for ($i = 0; $i < $this->serverProviderCount; $i++) { + ServerProvider::factory()->ownedBy($token)->createForTest(); + } + } + + // Create default servers + Network::factory($this->networkCount) + ->ownedBy($token) + ->create() + ->each(fn ($network) => Server::factory($this->serverCount)->create(['network_id' => $network->id])); + + // Default Networks + if ($this->defaultNetworks) { + $token->networks()->create(['name' => 'devnet']); + $token->networks()->create(['name' => 'testnet']); + } + + // Invitations + if ($this->invitationsCount > 0) { + Invitation::factory($this->invitationsCount)->create(['token_id' => $token->id]); + } + + return Token::findOrFail($token->id); + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..f933344 --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,47 @@ + $this->faker->firstName(), + 'email' => $this->faker->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'timezone' => 'UTC', + 'remember_token' => Str::random(10), + ]; + } +} diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php new file mode 100644 index 0000000..5968d53 --- /dev/null +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,38 @@ +bigIncrements('id'); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->string('timezone')->default('UTC')->nullable(); + $table->rememberToken(); + $table->schemalessAttributes('extra_attributes'); + $table->timestamp('seen_welcome_screens_at')->nullable(); + $table->timestamp('seen_notifications_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('users'); + } +} diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php new file mode 100644 index 0000000..a983a76 --- /dev/null +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -0,0 +1,30 @@ +string('email')->index(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('password_resets'); + } +} diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php new file mode 100644 index 0000000..918bc7c --- /dev/null +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -0,0 +1,30 @@ +text('two_factor_secret') + ->after('password') + ->nullable(); + + $table->text('two_factor_recovery_codes') + ->after('two_factor_secret') + ->nullable(); + }); + } + + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('two_factor_secret', 'two_factor_recovery_codes'); + }); + } +} diff --git a/database/migrations/2020_01_14_000000_create_failed_jobs_table.php b/database/migrations/2020_01_14_000000_create_failed_jobs_table.php new file mode 100644 index 0000000..949b19d --- /dev/null +++ b/database/migrations/2020_01_14_000000_create_failed_jobs_table.php @@ -0,0 +1,37 @@ +bigIncrements('id'); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('failed_jobs'); + } +} diff --git a/database/migrations/2020_01_15_000000_create_activity_log_table.php b/database/migrations/2020_01_15_000000_create_activity_log_table.php new file mode 100644 index 0000000..5a19e66 --- /dev/null +++ b/database/migrations/2020_01_15_000000_create_activity_log_table.php @@ -0,0 +1,40 @@ +create(config('activitylog.table_name'), function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('log_name')->nullable(); + $table->text('description'); + $table->unsignedBigInteger('subject_id')->nullable(); + $table->string('subject_type')->nullable(); + $table->unsignedBigInteger('causer_id')->nullable(); + $table->string('causer_type')->nullable(); + $table->json('properties')->nullable(); + $table->timestamps(); + + $table->index('log_name'); + $table->index(['subject_id', 'subject_type'], 'subject'); + $table->index(['causer_id', 'causer_type'], 'causer'); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::connection(config('activitylog.database_connection'))->dropIfExists(config('activitylog.table_name')); + } +} diff --git a/database/migrations/2020_01_15_100000_create_statuses_table.php b/database/migrations/2020_01_15_100000_create_statuses_table.php new file mode 100644 index 0000000..26798bd --- /dev/null +++ b/database/migrations/2020_01_15_100000_create_statuses_table.php @@ -0,0 +1,26 @@ +increments('id'); + $table->string('name'); + $table->text('reason')->nullable(); + $table->morphs('model'); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('statuses'); + } +} diff --git a/database/migrations/2020_01_15_101832_create_coin_table.php b/database/migrations/2020_01_15_101832_create_coin_table.php new file mode 100644 index 0000000..304c966 --- /dev/null +++ b/database/migrations/2020_01_15_101832_create_coin_table.php @@ -0,0 +1,36 @@ +bigIncrements('id'); + $table->string('name', 100)->index(); + $table->string('symbol', 10); + $table->string('slug', 100); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('coins'); + } +} diff --git a/database/migrations/2020_01_16_000000_create_tokens_table.php b/database/migrations/2020_01_16_000000_create_tokens_table.php new file mode 100644 index 0000000..54fb6d9 --- /dev/null +++ b/database/migrations/2020_01_16_000000_create_tokens_table.php @@ -0,0 +1,49 @@ +bigIncrements('id'); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->foreignId('coin_id')->constrained()->cascadeOnDelete(); + $table->string('name')->index(); + $table->string('slug')->nullable(); + $table->json('config')->nullable(); + $table->schemalessAttributes('extra_attributes'); + $table->json('keypair')->nullable(); + $table->timestamp('onboarded_at')->nullable(); + $table->timestamps(); + $table->softDeletes(); + }); + + Schema::create('token_users', function (Blueprint $table) { + $table->foreignId('token_id')->constrained()->cascadeOnDelete(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->string('role', 20); + $table->json('permissions'); + $table->timestamps(); + + $table->unique(['token_id', 'user_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('token_users'); + Schema::dropIfExists('tokens'); + } +} diff --git a/database/migrations/2020_01_16_100000_create_server_providers_table.php b/database/migrations/2020_01_16_100000_create_server_providers_table.php new file mode 100644 index 0000000..701e666 --- /dev/null +++ b/database/migrations/2020_01_16_100000_create_server_providers_table.php @@ -0,0 +1,92 @@ +bigIncrements('id'); + $table->foreignId('token_id')->constrained()->cascadeOnDelete(); + $table->string('type'); + $table->string('name'); + $table->unique(['token_id', 'name']); + $table->string('provider_key_id')->nullable(); + $table->schemalessAttributes('extra_attributes'); + $table->timestamps(); + }); + + Schema::create('server_provider_plans', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('uuid'); + $table->unsignedInteger('disk'); + $table->unsignedInteger('memory'); + $table->unsignedInteger('cores'); + $table->json('regions'); + $table->timestamps(); + + $table->unique(['uuid']); + }); + + Schema::create('server_provider_server_provider_plan', function (Blueprint $table) { + $table->foreignId('server_provider_id')->constrained()->cascadeOnDelete(); + $table->foreignId('server_provider_plan_id')->constrained()->cascadeOnDelete(); + + $table->unique(['server_provider_id', 'server_provider_plan_id']); + }); + + Schema::create('server_provider_regions', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('uuid'); + $table->string('name'); + $table->timestamps(); + + $table->unique(['uuid']); + }); + + Schema::create('server_provider_server_provider_region', function (Blueprint $table) { + $table->foreignId('server_provider_id')->constrained()->cascadeOnDelete(); + $table->foreignId('server_provider_region_id')->constrained()->cascadeOnDelete(); + + $table->unique(['server_provider_id', 'server_provider_region_id']); + }); + + Schema::create('server_provider_images', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('uuid'); + $table->string('name'); + $table->timestamps(); + + $table->unique(['uuid']); + }); + + Schema::create('server_provider_server_provider_image', function (Blueprint $table) { + $table->foreignId('server_provider_id')->constrained()->cascadeOnDelete(); + $table->foreignId('server_provider_image_id')->constrained()->cascadeOnDelete(); + + $table->unique(['server_provider_id', 'server_provider_image_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('server_provider_server_provider_plan'); + Schema::dropIfExists('server_provider_server_provider_region'); + Schema::dropIfExists('server_provider_server_provider_image'); + Schema::dropIfExists('server_provider_plans'); + Schema::dropIfExists('server_provider_regions'); + Schema::dropIfExists('server_provider_images'); + Schema::dropIfExists('server_providers'); + } +} diff --git a/database/migrations/2020_01_16_300000_create_networks_table.php b/database/migrations/2020_01_16_300000_create_networks_table.php new file mode 100644 index 0000000..17948f4 --- /dev/null +++ b/database/migrations/2020_01_16_300000_create_networks_table.php @@ -0,0 +1,31 @@ +bigIncrements('id'); + $table->foreignId('token_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('networks'); + } +} diff --git a/database/migrations/2020_01_16_400000_create_servers_table.php b/database/migrations/2020_01_16_400000_create_servers_table.php new file mode 100644 index 0000000..0fd00b6 --- /dev/null +++ b/database/migrations/2020_01_16_400000_create_servers_table.php @@ -0,0 +1,46 @@ +bigIncrements('id'); + $table->foreignId('network_id')->constrained()->cascadeOnDelete(); + $table->foreignId('server_provider_id')->constrained()->cascadeOnDelete(); + $table->foreignId('server_provider_plan_id')->constrained(); + $table->foreignId('server_provider_region_id')->constrained(); + $table->foreignId('server_provider_image_id')->constrained(); + $table->string('name'); + $table->text('user_password')->nullable(); + $table->text('sudo_password')->nullable(); + $table->text('delegate_passphrase')->nullable(); + $table->text('delegate_password')->nullable(); + $table->unsignedInteger('provider_server_id')->nullable(); + $table->ipAddress('ip_address')->nullable(); + $table->timestamp('provisioning_job_dispatched_at')->nullable(); + $table->timestamp('provisioned_at')->nullable(); + $table->string('preset'); + $table->string('core_version')->nullable(); + $table->schemalessAttributes('extra_attributes'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('servers'); + } +} diff --git a/database/migrations/2020_01_16_500000_create_secure_shell_keys_table.php b/database/migrations/2020_01_16_500000_create_secure_shell_keys_table.php new file mode 100644 index 0000000..7ec7899 --- /dev/null +++ b/database/migrations/2020_01_16_500000_create_secure_shell_keys_table.php @@ -0,0 +1,37 @@ +bigIncrements('id'); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->text('public_key'); + $table->string('fingerprint'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('secure_shell_keys'); + } +} diff --git a/database/migrations/2020_01_17_100000_create_invitations_table.php b/database/migrations/2020_01_17_100000_create_invitations_table.php new file mode 100644 index 0000000..e7dfba7 --- /dev/null +++ b/database/migrations/2020_01_17_100000_create_invitations_table.php @@ -0,0 +1,39 @@ +bigIncrements('id'); + $table->uuid('uuid'); + $table->foreignId('token_id')->constrained()->cascadeOnDelete(); + $table->foreignId('user_id')->cascadeOnDelete()->nullable(); + $table->string('email'); + $table->string('role'); + $table->json('permissions'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('invitations'); + } +} diff --git a/database/migrations/2020_01_22_052713_create_media_table.php b/database/migrations/2020_01_22_052713_create_media_table.php new file mode 100644 index 0000000..26c1509 --- /dev/null +++ b/database/migrations/2020_01_22_052713_create_media_table.php @@ -0,0 +1,45 @@ +bigIncrements('id'); + + $table->morphs('model'); + $table->uuid('uuid')->nullable()->unique(); + $table->string('collection_name'); + $table->string('name'); + $table->string('file_name'); + $table->string('mime_type')->nullable(); + $table->string('disk'); + $table->string('conversions_disk')->nullable(); + $table->unsignedBigInteger('size'); + $table->json('manipulations'); + $table->json('custom_properties'); + $table->json('generated_conversions'); + $table->json('responsive_images'); + $table->unsignedInteger('order_column')->nullable(); + + $table->nullableTimestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + { + Schema::dropIfExists('media'); + } +} diff --git a/database/migrations/2020_02_05_030355_create_server_tasks_table.php b/database/migrations/2020_02_05_030355_create_server_tasks_table.php new file mode 100644 index 0000000..6b19d1a --- /dev/null +++ b/database/migrations/2020_02_05_030355_create_server_tasks_table.php @@ -0,0 +1,41 @@ +bigIncrements('id'); + $table->foreignId('server_id')->constrained()->cascadeOnDelete(); + $table->string('type'); + $table->string('name'); + $table->string('user'); + $table->integer('exit_code')->nullable(); + $table->longText('script'); + $table->longText('output'); + $table->json('options'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('server_tasks'); + } +} diff --git a/database/migrations/2020_05_20_114046_create_token_secure_shell_keys.php b/database/migrations/2020_05_20_114046_create_token_secure_shell_keys.php new file mode 100644 index 0000000..fad966a --- /dev/null +++ b/database/migrations/2020_05_20_114046_create_token_secure_shell_keys.php @@ -0,0 +1,35 @@ +foreignId('token_id')->constrained()->cascadeOnDelete(); + $table->foreignId('secure_shell_key_id')->constrained()->cascadeOnDelete(); + + $table->unique(['token_id', 'secure_shell_key_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('secure_shell_key_token'); + } +} diff --git a/database/migrations/2020_09_16_135202_add_uuid_to_failed_jobs_table.php b/database/migrations/2020_09_16_135202_add_uuid_to_failed_jobs_table.php new file mode 100644 index 0000000..b1895b7 --- /dev/null +++ b/database/migrations/2020_09_16_135202_add_uuid_to_failed_jobs_table.php @@ -0,0 +1,34 @@ +string('uuid')->after('id')->nullable()->unique(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('failed_jobs', function (Blueprint $table) { + $table->dropColumn('uuid'); + }); + } +} diff --git a/database/migrations/2020_10_21_171258_add_last_login_at_to_users_table.php b/database/migrations/2020_10_21_171258_add_last_login_at_to_users_table.php new file mode 100644 index 0000000..83dcd5d --- /dev/null +++ b/database/migrations/2020_10_21_171258_add_last_login_at_to_users_table.php @@ -0,0 +1,17 @@ +timestamp('last_login_at')->nullable(); + }); + } +} diff --git a/database/migrations/2020_11_17_000000_create_notifications_table.php b/database/migrations/2020_11_17_000000_create_notifications_table.php new file mode 100644 index 0000000..3606971 --- /dev/null +++ b/database/migrations/2020_11_17_000000_create_notifications_table.php @@ -0,0 +1,25 @@ +uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->morphs('relatable'); + $table->nullableMorphs('relatable_logo'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->boolean('is_starred')->default(false); + $table->timestamps(); + }); + } +} diff --git a/database/migrations/2022_01_26_092328_add_event_column_to_activity_log_table.php b/database/migrations/2022_01_26_092328_add_event_column_to_activity_log_table.php new file mode 100644 index 0000000..742e420 --- /dev/null +++ b/database/migrations/2022_01_26_092328_add_event_column_to_activity_log_table.php @@ -0,0 +1,24 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->string('event')->nullable()->after('subject_type'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('event'); + }); + } +} diff --git a/database/migrations/2022_01_26_092329_add_batch_uuid_column_to_activity_log_table.php b/database/migrations/2022_01_26_092329_add_batch_uuid_column_to_activity_log_table.php new file mode 100644 index 0000000..ad42e5b --- /dev/null +++ b/database/migrations/2022_01_26_092329_add_batch_uuid_column_to_activity_log_table.php @@ -0,0 +1,24 @@ +table(config('activitylog.table_name'), function (Blueprint $table) { + $table->uuid('batch_uuid')->nullable()->after('properties'); + }); + } + + public function down() + { + Schema::connection(config('activitylog.database_connection'))->table(config('activitylog.table_name'), function (Blueprint $table) { + $table->dropColumn('batch_uuid'); + }); + } +} diff --git a/database/migrations/2022_06_06_211404_add_deleted_at_column_to_server_providers_table.php b/database/migrations/2022_06_06_211404_add_deleted_at_column_to_server_providers_table.php new file mode 100644 index 0000000..9197209 --- /dev/null +++ b/database/migrations/2022_06_06_211404_add_deleted_at_column_to_server_providers_table.php @@ -0,0 +1,21 @@ +softDeletes(); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..df9ecc9 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,19 @@ + + + + + ./tests/Analysis + + + ./tests/App + + + ./tests/Domain + + + ./tests/Support + + + + + ./app + + ./app/App/Console/Playbooks + ./app/App/Console/Commands/RunPlaybookCommand.php + ./app/App/Exceptions + ./app/App/Nova + ./app/App/Providers + ./app/App/User/Controllers/Auth + ./app/Support/Eloquent/Concerns + ./app/App/BaseApplication.php + ./app/App/Console/Kernel.php + ./app/App/Token/Requests/UpdateTokenLogoRequest.php + ./app/App/User/Requests/UpdateUserPhotoRequest.php + ./app/Console/Kernel.php + ./app/Domain/Server/Services/Providers/AWS.php + ./app/Support/Components/Component.php + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..a8e7929 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,63 @@ + + + + + ./tests/Analysis + + + ./tests/App + + + ./tests/Domain + + + ./tests/Support + + + + + ./app + + ./app/App/Console/Playbooks + ./app/App/Console/Commands/RunPlaybookCommand.php + ./app/App/Exceptions + ./app/App/Nova + ./app/App/Providers + ./app/App/User/Controllers/Auth + ./app/Support/Eloquent/Concerns + ./app/App/BaseApplication.php + ./app/App/Console/Kernel.php + ./app/App/Token/Requests/UpdateTokenLogoRequest.php + ./app/App/User/Requests/UpdateUserPhotoRequest.php + ./app/Console/Kernel.php + ./app/Domain/Server/Services/Providers/AWS.php + ./app/Support/Components/Component.php + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..aaf2520 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..3aec5e2 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..e796fd7 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..c8ee2b1 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..6cb678b Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/browserconfig.xml b/public/browserconfig.xml new file mode 100644 index 0000000..ef21a70 --- /dev/null +++ b/public/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #5452ce + + + diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..c634f0e --- /dev/null +++ b/public/css/app.css @@ -0,0 +1,99 @@ +/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}#newsletter input[type=email]{border-bottom-left-radius:.25rem!important;border-bottom-right-radius:0!important;border-style:none!important;border-top-left-radius:.25rem!important;border-top-right-radius:0!important}#newsletter button[type=submit]{border-bottom-left-radius:0!important;border-bottom-right-radius:.25rem!important;border-top-left-radius:0!important;border-top-right-radius:.25rem!important;padding-left:1rem!important;padding-right:1rem!important}#newsletter button[type=submit].focus-visible,.button-pagination-page-indicator--selected.focus-visible,.button-pagination-page-indicator.focus-visible,.review-content a.focus-visible,a.link.focus-visible,a[dusk*=navbar-item-].focus-visible,button.link.focus-visible{border-radius:.25rem}#newsletter button[type=submit]:focus-visible,.button-pagination-page-indicator--selected:focus-visible,.button-pagination-page-indicator:focus-visible,.review-content a:focus-visible,a.link:focus-visible,a[dusk*=navbar-item-]:focus-visible,button.link:focus-visible{border-radius:.25rem}[role=button],a,button,label.tile-selection-option input{outline:2px solid transparent;outline-offset:2px}[role=button].focus-visible,a.focus-visible,button.focus-visible,label.tile-selection-option input.focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-color:var(--theme-color-primary-500);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);-webkit-text-decoration-line:none;text-decoration-line:none;transition-property:none;z-index:10}[role=button]:focus-visible,a:focus-visible,button:focus-visible,label.tile-selection-option input:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-color:var(--theme-color-primary-500);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);-webkit-text-decoration-line:none;text-decoration-line:none;transition-property:none;z-index:10}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}@media (min-width:1550px){.container{max-width:1550px}}.documentation-sidebar .alert-wrapper .alert-content-wrapper+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.alert-wrapper .alert-content-wrapper{border-radius:.75rem;display:flex;flex-direction:column;overflow:hidden}.documentation-sidebar .alert-wrapper .alert-title+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.alert-wrapper .alert-title{align-items:center;display:flex;margin:0;padding:.5rem 1rem}.alert-wrapper .alert-title .alert-icon{display:inline-flex;height:.875rem;margin-right:.5rem;width:.875rem}.alert-wrapper .alert-title span{font-size:.875rem;font-weight:600;line-height:1.25rem;line-height:1}.alert-wrapper .alert-title button{color:var(--theme-color-secondary-900);display:inline-flex;margin-left:auto}.alert-wrapper .alert-title button svg{display:inline-flex;height:.875rem;width:.875rem}.alert-wrapper.alert-info .alert-title{background-color:var(--theme-color-info-100);color:var(--theme-color-info-700)}.alert-wrapper.alert-success .alert-title{background-color:var(--theme-color-success-100);color:var(--theme-color-success-700)}.alert-wrapper.alert-warning .alert-title{background-color:var(--theme-color-warning-100);color:var(--theme-color-warning-900)}.alert-wrapper.alert-error .alert-title{background-color:var(--theme-color-danger-100);color:var(--theme-color-danger-700)}.alert-wrapper.alert-hint .alert-title{background-color:var(--theme-color-hint-100);color:var(--theme-color-hint-700)}.alert-wrapper .alert-content{color:var(--theme-color-secondary-900);font-size:.875rem;line-height:1.5rem;padding:1rem}.alert-wrapper.alert-info .alert-content{background-color:var(--theme-color-info-50)}.alert-wrapper.alert-success .alert-content{background-color:var(--theme-color-success-50)}.alert-wrapper.alert-warning .alert-content{background-color:var(--theme-color-warning-50)}.alert-wrapper.alert-error .alert-content{background-color:var(--theme-color-danger-50)}.alert-wrapper.alert-hint .alert-content{background-color:var(--theme-color-hint-50)}.dark .alert-wrapper .alert-title{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark .alert-wrapper .alert-title button{color:var(--theme-color-secondary-200)}.dark .alert-wrapper.alert-info .alert-title{background-color:var(--theme-color-info-700)}.dark .alert-wrapper.alert-success .alert-title{background-color:var(--theme-color-success-700)}.dark .alert-wrapper.alert-warning .alert-title{background-color:var(--theme-color-warning-700)}.dark .alert-wrapper.alert-error .alert-title{background-color:var(--theme-color-danger-500)}.dark .alert-wrapper.alert-hint .alert-title{background-color:var(--theme-color-hint-700)}.dark .alert-wrapper .alert-content-wrapper>.alert-title~.alert-content{color:var(--theme-color-secondary-200)}.dark .alert-wrapper.alert-error .alert-content-wrapper>.alert-title~.alert-content,.dark .alert-wrapper.alert-hint .alert-content-wrapper>.alert-title~.alert-content,.dark .alert-wrapper.alert-info .alert-content-wrapper>.alert-title~.alert-content,.dark .alert-wrapper.alert-success .alert-content-wrapper>.alert-title~.alert-content,.dark .alert-wrapper.alert-warning .alert-content-wrapper>.alert-title~.alert-content{background-color:var(--theme-color-secondary-800)}.button-generic,.button-primary{border-radius:.25rem;font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}a.button-primary{display:inline-block}.button-primary{--tw-text-opacity:1;background-color:var(--theme-color-primary-600);color:rgb(255 255 255/var(--tw-text-opacity))}.button-primary:hover{background-color:var(--theme-color-primary-700)}.button-cancel:disabled,.button-disabled,.button-icon-rounded:disabled,.button-icon:disabled,.button-primary:disabled,.button-secondary:disabled,.button-tertiary:disabled,a.disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.button-outline.button-disabled,.button-outline:disabled,.button-tag-outline.button-disabled,.button-tag-outline:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;border-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .button-cancel:disabled,.dark .button-disabled,.dark .button-icon-rounded:disabled,.dark .button-icon:disabled,.dark .button-primary:disabled,.dark .button-secondary:disabled,.dark .button-tertiary:disabled,.dark a.disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.dark .button-outline.button-disabled,.dark .button-outline:disabled,.dark .button-tag-outline.button-disabled,.dark .button-tag-outline:disabled{border-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.button-secondary{border-radius:.25rem;font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}a.button-secondary{display:inline-block}.button-secondary{background-color:var(--theme-color-primary-100);color:var(--theme-color-primary-600)}.button-cancel{border-radius:.25rem;font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}a.button-cancel{display:inline-block}.button-cancel{background-color:var(--theme-color-danger-100);color:var(--theme-color-danger-400)}.dark .button-cancel{--tw-text-opacity:1;background-color:var(--theme-color-danger-400);color:rgb(255 255 255/var(--tw-text-opacity))}.dark .button-cancel:hover{background-color:var(--theme-color-danger-500)}.button-icon:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .button-icon:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.button-icon{background-color:var(--theme-color-primary-100);border-radius:.25rem;color:var(--theme-color-primary-600);font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}.dark .button-icon{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.button-icon:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.button-icon:hover,.dark .button-icon:hover{background-color:var(--theme-color-primary-700)}.dark .button-icon:hover{color:var(--theme-color-secondary-200)}a.button-icon{display:inline-block}.dark .button-icon:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.documentation-content a.button-icon:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.documentation-content .page-ref .button-icon{border-radius:0}.button-icon-cancel:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .button-icon-cancel:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.button-icon-cancel{border-radius:.25rem;font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}a.button-icon-cancel{display:inline-block}.button-icon-cancel{background-color:var(--theme-color-danger-100);color:var(--theme-color-danger-400)}.dark .button-icon-cancel{--tw-text-opacity:1;background-color:var(--theme-color-danger-400);color:rgb(255 255 255/var(--tw-text-opacity))}.dark .button-icon-cancel:hover{background-color:var(--theme-color-danger-500)}.button-icon-cancel:hover{--tw-text-opacity:1;background-color:var(--theme-color-danger-400);color:rgb(255 255 255/var(--tw-text-opacity))}.documentation-sidebar .button-icon+h2:not(.documentation-sidebar h2:first-of-type),.documentation-sidebar .button-icon-cancel+h2:not(.documentation-sidebar h2:first-of-type),.documentation-sidebar .button-icon-primary+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.button-icon,.button-icon-cancel,.button-icon-primary{align-items:center;display:flex;justify-content:center;padding:0}.dark .button-icon,.dark .button-icon-rounded,.dark .button-secondary,.dark .button-tag{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.dark .button-outline,.dark .button-tag-outline{border-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.button-icon-rounded:hover,.button-icon:hover,.button-secondary:hover,.button-tag:hover{--tw-text-opacity:1;background-color:var(--theme-color-primary-700);color:rgb(255 255 255/var(--tw-text-opacity))}.dark .button-icon-rounded:hover,.dark .button-icon:hover,.dark .button-secondary:hover,.dark .button-tag:hover{background-color:var(--theme-color-primary-700);color:var(--theme-color-secondary-200)}.dark .button-outline:hover,.dark .button-tag-outline:hover{border-color:var(--theme-color-primary-700);color:var(--theme-color-secondary-200)}.button-cancel:hover,.button-icon-cancel:hover{--tw-text-opacity:1;background-color:var(--theme-color-danger-400);color:rgb(255 255 255/var(--tw-text-opacity))}a.button-generic,a.button-primary,a.button-secondary,a.button-tertiary{display:inline-block}.button-pagination-page-indicator{background-color:var(--theme-color-primary-100);color:var(--theme-color-primary-600);font-weight:600;padding:.625rem .5rem;text-align:center;transition:all .1s ease-in}.button-pagination-page-indicator .button-pagination-ellipsis,.button-pagination-page-indicator .button-pagination-search{transition-duration:.1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.button-pagination-page-indicator .button-pagination-search{margin-top:.25rem;position:absolute}.button-pagination-page-indicator .button-pagination-ellipsis,.button-pagination-page-indicator:hover .button-pagination-search{opacity:1}.button-pagination-page-indicator .button-pagination-search,.button-pagination-page-indicator:hover .button-pagination-ellipsis{opacity:0}.dark .button-pagination-page-indicator{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.button-pagination-page-indicator--selected{background-color:var(--theme-color-primary-200);color:var(--theme-color-primary-600);font-weight:600;padding:.625rem .5rem;text-align:center;transition:all .1s ease-in}.dark .button-pagination-page-indicator--selected{background-color:var(--theme-color-secondary-600);color:var(--theme-color-secondary-200);font-weight:600;padding:.625rem .5rem;text-align:center;transition:all .1s ease-in}.button-pagination-page-indicator:hover{--tw-text-opacity:1;background-color:var(--theme-color-primary-700);border-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));transform:scale(1.2)}.dark .button-pagination-page-indicator:hover:not([disabled]){background-color:var(--theme-color-primary-600)}.dark .button-icon-primary:hover,.dark .button-icon-rounded:hover,.dark .button-icon:hover,.dark .button-primary:hover,.dark .button-secondary:hover,.dark .button-tertiary:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.view-option-button{position:relative}.view-option-button.active:not(.focus-visible):before{background-color:var(--theme-color-primary-600);bottom:0;content:"";height:3px;left:0;position:absolute;right:0}.view-option-button.active:not(:focus-visible):before{background-color:var(--theme-color-primary-600);bottom:0;content:"";height:3px;left:0;position:absolute;right:0}code.hljs{border-radius:.75rem;font-family:FiraMono;padding:1.5rem 2rem}code.hljs .hljs-ln-n{padding-right:1rem;text-align:right}.table-container table>tbody>tr>tdcode.hoverable-cell.hljs .hljs-ln-n>div.table-cell-content{justify-content:flex-end}.documentation-content{color:var(--theme-color-secondary-700);overflow-wrap:break-word}.dark .documentation-content{color:var(--theme-color-secondary-500)}.documentation-content h1{margin-bottom:2rem}.documentation-content h2{border-color:var(--theme-color-secondary-200);border-top-width:1px;margin-bottom:1rem;margin-top:1.5rem;padding-top:1.5rem}.dark .documentation-content h2{border-color:var(--theme-color-secondary-800)}.documentation-content h3{margin-bottom:1rem}@media (min-width:640px){.documentation-content h2{margin-top:2.5rem;padding-top:2.5rem}}.documentation-content .alert-wrapper,.documentation-content .embed-link,.documentation-content .grid-gallery,.documentation-content .link-collection,.documentation-content .page-ref,.documentation-content .table-wrapper,.documentation-content :not(.table-wrapper) table,.documentation-content ol,.documentation-content pre,.documentation-content summary,.documentation-content ul{margin-bottom:1.5rem}.documentation-content .accordion .table-wrapper,.documentation-content .accordion table{margin-bottom:0}.documentation-content p{line-height:1.75rem;margin-bottom:1.5rem}.documentation-content .alert-content-wrapper p{margin-bottom:0}.documentation-content code{background-color:var(--theme-color-secondary-200);border-radius:.25rem;color:var(--theme-color-secondary-900);font-weight:400;padding:.25rem .5rem}.dark .documentation-content code{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-400)}.documentation-content pre.hljs{margin-bottom:0!important}.documentation-content pre.hljs>code{background-color:inherit!important;color:inherit!important;padding:0!important}.documentation-content a{color:var(--theme-color-primary-600);font-weight:600;-webkit-text-decoration-line:none;text-decoration-line:none;transition:all .1s ease-in}.simple-markdown a:is(.documentation-content a):hover{text-decoration:none}.documentation-content a[target=_blank]:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.documentation-content a[target=_blank]:hover):hover{text-decoration:none}.documentation-content a:hover,.documentation-content a[target=_blank]:hover>span{-webkit-text-decoration-line:underline;text-decoration-line:underline}.documentation-content a:hover{color:var(--theme-color-primary-700)}.documentation-content a:active{color:var(--theme-color-primary-400)}.documentation-content ul{list-style-position:outside;list-style-type:disc;padding-left:1rem}.documentation-content ol{list-style-position:outside;list-style-type:decimal;padding-left:1rem}.documentation-content ol ul,.documentation-content ul ul{list-style-position:outside;list-style-type:circle;margin-bottom:0;margin-left:1rem}.documentation-content ol ol,.documentation-content ul ol{list-style-position:outside;list-style-type:lower-latin;margin-bottom:0;margin-left:1rem}.documentation-content ol>li,.documentation-content ul>li{padding-bottom:.5rem}.documentation-content hr:not(.custom-separator){background-color:var(--theme-color-secondary-300);border-color:var(--theme-color-secondary-300);margin-bottom:1.5rem;margin-top:1.5rem}.dark .documentation-content hr:not(.custom-separator){background-color:var(--theme-color-secondary-800);border-color:var(--theme-color-secondary-800)}.documentation-content img{display:block;margin-left:auto;margin-right:auto}.documentation-sidebar .documentation-content .image-container+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.documentation-content .image-container{align-items:center;display:flex;flex-direction:column}.documentation-content .video-container{width:100%}.documentation-content .image-container .twitter-tweet,.documentation-content .typeform-widget,.documentation-content iframe,.documentation-content img{border-color:var(--theme-color-secondary-300);border-radius:.75rem;border-width:1px;overflow:hidden}.dark .documentation-content .image-container .twitter-tweet,.dark .documentation-content .typeform-widget,.dark .documentation-content iframe,.dark .documentation-content img{border-color:var(--theme-color-secondary-800)}.documentation-content>.twitter-tweet{margin-left:auto;margin-right:auto}.documentation-content .image-container .twitter-tweet{max-width:548px;overflow:hidden}.documentation-content .image-container .twitter-tweet iframe{border-width:0;margin:-1px}.documentation-content .image-caption{border-color:var(--theme-color-secondary-300);border-left-width:2px;color:var(--theme-color-secondary-800);display:block;font-size:.875rem;font-style:italic;line-height:1.25rem;margin-left:auto;margin-right:auto;margin-top:.75rem;padding-left:.75rem;padding-right:.75rem;position:relative;text-align:center}.dark .documentation-content .image-caption{border-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.documentation-content .image-caption .external-link svg{height:.625rem;margin-top:-.25rem;width:.625rem}.documentation-content .embed-link a:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.documentation-content .embed-link a:hover):hover{text-decoration:none}.documentation-content .embed-link img{border-style:none}.documentation-content a.button-secondary:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.documentation-content .page-ref h3{margin-bottom:0}.documentation-content .page-ref .button-secondary{border-radius:0}.documentation-content blockquote{border-color:var(--theme-color-secondary-300);border-left-width:2px;color:var(--theme-color-secondary-500);display:block;padding-left:1rem}.dark .documentation-content blockquote{border-color:var(--theme-color-secondary-700);color:var(--theme-color-secondary-700)}.documentation-content table{text-align:left;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.documentation-content table)>div.table-cell-content{justify-content:flex-start}.documentation-content table thead{color:var(--theme-color-secondary-500);font-size:.875rem;font-weight:600;line-height:1.25rem}.documentation-content table thead tr{border-bottom-width:1px;border-color:var(--theme-color-secondary-300);text-align:left}.table-container table>tbody>tr>td.hoverable-cell:is(.documentation-content table thead tr)>div.table-cell-content{justify-content:flex-start}.dark .documentation-content table thead tr{border-color:var(--theme-color-secondary-800)}.documentation-content table thead th{padding:.75rem;position:relative}.documentation-content table thead th:not(:last-child):after{border-color:var(--theme-color-secondary-300);border-left-width:1px;content:"";height:50%;position:absolute;right:0}.dark .documentation-content table thead th:not(:last-child):after{border-color:var(--theme-color-secondary-800)}.documentation-content table tbody td{line-height:1.25rem;padding:1rem .75rem}.documentation-content table tbody tr{border-bottom:1px var(--theme-color-secondary-300);border-left-color:var(--theme-color-secondary-300);border-right-color:var(--theme-color-secondary-300);border-style:dashed;border-top-color:var(--theme-color-secondary-300)}.dark .documentation-content table tbody tr{border-color:var(--theme-color-secondary-800)}.documentation-content table tbody tr:last-child{border-width:0}.documentation-content .table-wrapper{scrollbar-color:#e5f0f8 #bad6f0}.documentation-content .table-wrapper::-webkit-scrollbar{background-color:var(--theme-color-primary-100);border-radius:.5rem;height:6px;width:6px}.documentation-content .table-wrapper::-webkit-scrollbar-thumb{background-color:var(--theme-color-primary-200);border-radius:.5rem}.documentation-sidebar .flex+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.mobile-menu.documentation-sidebar h2 .heading-permalink{display:none}.mobile-menu.documentation-sidebar h2:first-child{border-width:0;margin-top:0;padding-top:.5rem}.documentation-content .heading-permalink,aside .heading-permalink{scroll-margin-top:120px}.documentation-content h2 .heading-permalink,.documentation-content h3 .heading-permalink,.documentation-content h4 .heading-permalink,main .documentation-content .heading-permalink{color:var(--theme-color-primary-600);margin-right:.75rem;transition:all .1s ease-in}.documentation-content h2 .heading-permalink:hover,.documentation-content h3 .heading-permalink:hover,.documentation-content h4 .heading-permalink:hover,main .documentation-content .heading-permalink:hover{color:var(--theme-color-primary-700);-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.documentation-content h2 .heading-permalink:hover):hover,.simple-markdown a:is(.documentation-content h3 .heading-permalink:hover):hover,.simple-markdown a:is(.documentation-content h4 .heading-permalink:hover):hover,.simple-markdown a:is(main .documentation-content .heading-permalink:hover):hover{text-decoration:none}.documentation-content .grid-gallery{display:grid;gap:1rem;grid-auto-flow:row;grid-template-columns:repeat(2,minmax(0,1fr))}.swiper-wrapper.documentation-content .grid-gallery .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.documentation-content .grid-gallery.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.documentation-content .grid-gallery.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.documentation-content .grid-gallery.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.documentation-content .grid-gallery.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:640px){.documentation-content .grid-gallery{grid-template-columns:repeat(3,minmax(0,1fr))}}.documentation-content .grid-gallery p{margin-bottom:0}.custom-code-block .hljs{overflow-x:auto}.documentation-content dl{line-height:1.75rem}.documentation-content dl dt{font-weight:600;padding-bottom:.25rem}.documentation-content dl dd{padding-bottom:1.5rem}.toast{align-items:center;border-radius:.75rem;color:var(--theme-color-secondary-900);display:inline-flex;flex-direction:column;font-size:.875rem;line-height:1.25rem;max-width:56rem;padding:1rem;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dark .toast{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-500)}@media (min-width:640px){.toast{flex-direction:row}.toast>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}}.toast-body{margin-top:1rem;text-align:center}@media (min-width:640px){.toast-body{margin-top:0;padding-right:1.5rem;text-align:left}}.documentation-sidebar .toast-icon+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.toast-icon{--tw-text-opacity:1;align-items:center;border-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));display:flex;flex-shrink:0;height:2.75rem;justify-content:center;width:2.75rem}.documentation-sidebar .toast-button+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.toast-button{align-items:center;border-radius:.25rem;color:var(--theme-color-secondary-900);display:flex;flex-shrink:0;height:2.75rem;justify-content:center;margin:1rem;position:absolute;right:0;top:0;width:2.75rem}@media (min-width:640px){.toast-button{margin:0;position:relative;right:auto;top:auto}}.toast-info{background-color:var(--theme-color-primary-50)}.toast-warning{background-color:var(--theme-color-warning-50)}.toast-danger{background-color:var(--theme-color-danger-50)}.toast-hint{background-color:var(--theme-color-hint-50)}.toast-success{background-color:var(--theme-color-success-50)}.toast-info .toast-icon{background-color:var(--theme-color-primary-600)}.toast-warning .toast-icon{background-color:var(--theme-color-warning-600)}.toast-danger .toast-icon{background-color:var(--theme-color-danger-400)}.toast-hint .toast-icon{background-color:var(--theme-color-hint-500)}.toast-success .toast-icon{background-color:var(--theme-color-success-600)}.toast-info .toast-button{background-color:var(--theme-color-primary-100)}.toast-info .toast-button:hover{background-color:var(--theme-color-primary-200)}.dark .toast-info .toast-button{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-600)}.dark .toast-info .toast-button:hover{background-color:var(--theme-color-secondary-500);color:var(--theme-color-secondary-400)}.toast-warning .toast-button{background-color:var(--theme-color-warning-100)}.toast-warning .toast-button:hover{background-color:var(--theme-color-warning-200)}.dark .toast-warning .toast-button{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-600)}.dark .toast-warning .toast-button:hover{background-color:var(--theme-color-secondary-500);color:var(--theme-color-secondary-400)}.toast-danger .toast-button{background-color:var(--theme-color-danger-100)}.toast-danger .toast-button:hover{background-color:var(--theme-color-danger-200)}.dark .toast-danger .toast-button{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-600)}.dark .toast-danger .toast-button:hover{background-color:var(--theme-color-secondary-500);color:var(--theme-color-secondary-400)}.toast-hint .toast-button{background-color:var(--theme-color-hint-100)}.toast-hint .toast-button:hover{background-color:var(--theme-color-hint-200)}.dark .toast-hint .toast-button{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-600)}.dark .toast-hint .toast-button:hover{background-color:var(--theme-color-secondary-500);color:var(--theme-color-secondary-400)}.toast-success .toast-button{background-color:var(--theme-color-success-100)}.toast-success .toast-button:hover{background-color:var(--theme-color-success-200)}.dark .toast-success .toast-button{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-600)}.dark .toast-success .toast-button:hover{background-color:var(--theme-color-secondary-500);color:var(--theme-color-secondary-400)}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:-webkit-sticky;position:sticky}.inset-0{bottom:0;left:0;right:0;top:0}.inset-2{bottom:.5rem;left:.5rem;right:.5rem;top:.5rem}.inset-y-0{bottom:0;top:0}.top-0{top:0}.right-0{right:0}.left-0{left:0}.bottom-0{bottom:0}.-top-1{top:-.25rem}.-left-2\.5px{left:-2.5px}.-left-2{left:-.5rem}.top-32{top:8rem}.top-1{top:.25rem}.right-1{right:.25rem}.bottom-5{bottom:1.25rem}.-top-10{top:-2.5rem}.right-13{right:3.25rem}.top-21{top:5.25rem}.top-2{top:.5rem}.right-2{right:.5rem}.bottom-2{bottom:.5rem}.left-2{left:.5rem}.z-40{z-index:40}.z-50{z-index:50}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-0{z-index:0}.m-0{margin:0}.m-auto{margin:auto}.-m-4{margin:-1rem}.-m-3{margin:-.75rem}.-m-1{margin:-.25rem}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-auto{margin-bottom:auto;margin-top:auto}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.-mx-8{margin-left:-2rem;margin-right:-2rem}.my-4{margin-bottom:1rem;margin-top:1rem}.mx-10{margin-left:2.5rem;margin-right:2.5rem}.my-1{margin-bottom:.25rem;margin-top:.25rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-8{margin-bottom:2rem;margin-top:2rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-8{margin-left:2rem;margin-right:2rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-0{margin-left:0;margin-right:0}.-my-px{margin-bottom:-1px;margin-top:-1px}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-3{margin-bottom:.75rem;margin-top:.75rem}.my-5{margin-bottom:1.25rem;margin-top:1.25rem}.my-7{margin-bottom:1.75rem;margin-top:1.75rem}.-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.mx-12{margin-left:3rem;margin-right:3rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mt-8{margin-top:2rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mr-6{margin-right:1.5rem}.mt-1{margin-top:.25rem}.ml-3{margin-left:.75rem}.mb-8{margin-bottom:2rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.ml-2{margin-left:.5rem}.mb-1\.5{margin-bottom:.375rem}.mb-1{margin-bottom:.25rem}.mt-3{margin-top:.75rem}.mr-2{margin-right:.5rem}.ml-1{margin-left:.25rem}.-mt-8{margin-top:-2rem}.mt-0{margin-top:0}.ml-10{margin-left:2.5rem}.mt-10{margin-top:2.5rem}.mr-10{margin-right:2.5rem}.mb-6{margin-bottom:1.5rem}.mb-5{margin-bottom:1.25rem}.mt-5{margin-top:1.25rem}.mb-2{margin-bottom:.5rem}.mr-4{margin-right:1rem}.-mt-4{margin-top:-1rem}.mt-0\.5{margin-top:.125rem}.ml-5{margin-left:1.25rem}.mb-16{margin-bottom:4rem}.ml-6{margin-left:1.5rem}.mr-3{margin-right:.75rem}.mr-5{margin-right:1.25rem}.-mt-1\.5{margin-top:-.375rem}.-mt-1{margin-top:-.25rem}.ml-0\.5{margin-left:.125rem}.ml-0{margin-left:0}.mr-1{margin-right:.25rem}.ml-7{margin-left:1.75rem}.-mr-1{margin-right:-.25rem}.-mt-5{margin-top:-1.25rem}.mb-0{margin-bottom:0}.-mr-5{margin-right:-1.25rem}.ml-8{margin-left:2rem}.-mt-2{margin-top:-.5rem}.-mr-2{margin-right:-.5rem}.mr-0{margin-right:0}.mb-3{margin-bottom:.75rem}.ml-px{margin-left:1px}.mt-24{margin-top:6rem}.ml-auto{margin-left:auto}.-mt-0\.5{margin-top:-.125rem}.-mt-0{margin-top:0}.box-border{box-sizing:border-box}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-0{height:0}.h-11{height:2.75rem}.h-20{height:5rem}.h-3{height:.75rem}.h-full{height:100%}.h-2{height:.5rem}.h-10{height:2.5rem}.h-16{height:4rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-5{height:1.25rem}.h-4{height:1rem}.h-48{height:12rem}.h-8{height:2rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-px{height:1px}.h-screen{height:100vh}.h-15{height:3.75rem}.h-21{height:5.25rem}.h-32{height:8rem}.h-1{height:.25rem}.h-4\.5{height:1.125rem}.h-13{height:3.25rem}.h-1\.5{height:.375rem}.h-28{height:7rem}.h-40{height:10rem}.h-auto{height:auto}.h-36{height:9rem}.max-h-80{max-height:20rem}.max-h-48{max-height:12rem}.max-h-full{max-height:100%}.w-full{width:100%}.w-60{width:15rem}.w-1\/3{width:33.333333%}.w-2\/3{width:66.666667%}.w-1\/2{width:50%}.w-0{width:0}.w-20{width:5rem}.w-32{width:8rem}.w-12{width:3rem}.w-2{width:.5rem}.w-11{width:2.75rem}.w-56{width:14rem}.w-1\/4{width:25%}.w-24{width:6rem}.w-64{width:16rem}.w-4{width:1rem}.w-48{width:12rem}.w-10{width:2.5rem}.w-16{width:4rem}.w-8{width:2rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-14{width:3.5rem}.w-screen{width:100vw}.w-96{width:24rem}.w-40{width:10rem}.w-3{width:.75rem}.w-15{width:3.75rem}.w-3\/4{width:75%}.w-5\/6{width:83.333333%}.w-1{width:.25rem}.w-4\.5{width:1.125rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-auto{width:auto}.w-21{width:5.25rem}.w-px{width:1px}.min-w-0{min-width:0}.min-w-full{min-width:100%}.min-w-max{min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content}.min-w-63{min-width:15.75rem}.max-w-lg{max-width:32rem}.max-w-full{max-width:100%}.max-w-2xl{max-width:42rem}.max-w-xl{max-width:36rem}.max-w-md{max-width:28rem}.max-w-5xl{max-width:64rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-134{max-width:33.5rem}.max-w-7xl{max-width:80rem}.max-w-doc{max-width:51.25rem}.max-w-error-image{max-width:697px}.max-w-6xl{max-width:72rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.origin-top-right{transform-origin:top right}.origin-top{transform-origin:top}.origin-bottom-right{transform-origin:bottom right}.translate-x-full{--tw-translate-x:100%}.translate-x-0,.translate-x-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x:0px}.translate-x-4{--tw-translate-x:1rem}.rotate-180,.translate-x-4{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.scale-95{--tw-scale-x:.95;--tw-scale-y:.95}.scale-95,.scale-100{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}.animate-pulse{-webkit-animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite;animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-spin{-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.grid-flow-row{grid-auto-flow:row}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-5{gap:1.25rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.gap-x-8{-moz-column-gap:2rem;column-gap:2rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-4{row-gap:1rem}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-16>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(4rem*var(--tw-space-y-reverse));margin-top:calc(4rem*(1 - var(--tw-space-y-reverse)))}.space-y-reverse>:not([hidden])~:not([hidden]){--tw-space-y-reverse:1}.divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)));border-right-width:calc(1px*var(--tw-divide-x-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-dashed>:not([hidden])~:not([hidden]){border-style:dashed}.divide-theme-secondary-200>:not([hidden])~:not([hidden]){border-color:var(--theme-color-secondary-200)}.divide-theme-secondary-300>:not([hidden])~:not([hidden]){border-color:var(--theme-color-secondary-300)}.divide-theme-secondary-800>:not([hidden])~:not([hidden]){border-color:var(--theme-color-secondary-800)}.divide-theme-primary-100>:not([hidden])~:not([hidden]){border-color:var(--theme-color-primary-100)}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded-xl{border-radius:.75rem}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.rounded-2xl{border-radius:1rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.rounded-b-xl{border-bottom-left-radius:.75rem;border-bottom-right-radius:.75rem}.rounded-b-lg{border-bottom-left-radius:.5rem;border-bottom-right-radius:.5rem}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-3{border-width:3px}.border-6{border-width:6px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-t-2{border-top-width:2px}.border-t-4{border-top-width:4px}.border-l-2{border-left-width:2px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-dotted{border-style:dotted}.border-none{border-style:none}.border-theme-secondary-300{border-color:var(--theme-color-secondary-300)}.border-theme-primary-100{border-color:var(--theme-color-primary-100)}.border-theme-primary-500{border-color:var(--theme-color-primary-500)}.border-theme-secondary-200{border-color:var(--theme-color-secondary-200)}.border-transparent{border-color:transparent}.border-theme-secondary-500{border-color:var(--theme-color-secondary-500)}.border-theme-warning-500{border-color:var(--theme-color-warning-500)}.border-theme-secondary-800{border-color:var(--theme-color-secondary-800)}.border-theme-secondary-900{border-color:var(--theme-color-secondary-900)}.border-theme-primary-700{border-color:var(--theme-color-primary-700)}.border-theme-danger-400{border-color:var(--theme-color-danger-400)}.border-theme-secondary-600{border-color:var(--theme-color-secondary-600)}.border-theme-primary-600{border-color:var(--theme-color-primary-600)}.border-theme-danger-500{border-color:var(--theme-color-danger-500)}.border-theme-secondary-400{border-color:var(--theme-color-secondary-400)}.border-white{--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}.border-theme-danger-100{border-color:var(--theme-color-danger-100)}.border-theme-secondary-700{border-color:var(--theme-color-secondary-700)}.border-theme-primary-200{border-color:var(--theme-color-primary-200)}.bg-theme-primary-100{background-color:var(--theme-color-primary-100)}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-theme-secondary-200{background-color:var(--theme-color-secondary-200)}.bg-theme-primary-50{background-color:var(--theme-color-primary-50)}.bg-theme-secondary-300{background-color:var(--theme-color-secondary-300)}.bg-theme-primary-600{background-color:var(--theme-color-primary-600)}.bg-theme-primary-500{background-color:var(--theme-color-primary-500)}.bg-theme-secondary-100{background-color:var(--theme-color-secondary-100)}.bg-theme-secondary-900{background-color:var(--theme-color-secondary-900)}.bg-transparent{background-color:transparent}.bg-theme-secondary-800{background-color:var(--theme-color-secondary-800)}.bg-theme-danger-400{background-color:var(--theme-color-danger-400)}.bg-theme-danger-50{background-color:var(--theme-color-danger-50)}.bg-theme-success-50{background-color:var(--theme-color-success-50)}.bg-theme-warning-50{background-color:var(--theme-color-warning-50)}.bg-theme-success-200{background-color:var(--theme-color-success-200)}.bg-theme-danger-100{background-color:var(--theme-color-danger-100)}.bg-theme-warning-100{background-color:var(--theme-color-warning-100)}.bg-theme-success-600{background-color:var(--theme-color-success-600)}.bg-theme-danger-200{background-color:var(--theme-color-danger-200)}.bg-theme-secondary-700{background-color:var(--theme-color-secondary-700)}.bg-theme-blog-background{background-color:var(--theme-color-blog-background)}.bg-theme-danger-500{background-color:var(--theme-color-danger-500)}.bg-theme-primary-700{background-color:var(--theme-color-primary-700)}.bg-opacity-90{--tw-bg-opacity:.9}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-l{background-image:linear-gradient(to left,var(--tw-gradient-stops))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.bg-contain{background-size:contain}.bg-cover{background-size:cover}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-center{background-position:50%}.bg-no-repeat{background-repeat:no-repeat}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-4{padding:1rem}.p-2{padding:.5rem}.p-0{padding:0}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-3{padding:.75rem}.p-1\.5{padding:.375rem}.p-1{padding:.25rem}.p-8{padding:2rem}.p-10{padding:2.5rem}.p-px{padding:1px}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-8{padding-bottom:2rem;padding-top:2rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-8{padding-left:2rem;padding-right:2rem}.py-12{padding-bottom:3rem;padding-top:3rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-0\.5{padding-bottom:.125rem;padding-top:.125rem}.py-0{padding-bottom:0;padding-top:0}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.pt-12{padding-top:3rem}.pb-8{padding-bottom:2rem}.pt-10{padding-top:2.5rem}.pb-10{padding-bottom:2.5rem}.pb-6{padding-bottom:1.5rem}.pr-10{padding-right:2.5rem}.pl-7{padding-left:1.75rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pr-4{padding-right:1rem}.pl-3{padding-left:.75rem}.pb-1{padding-bottom:.25rem}.pr-3{padding-right:.75rem}.pb-4{padding-bottom:1rem}.pb-3{padding-bottom:.75rem}.pb-2{padding-bottom:.5rem}.pr-6{padding-right:1.5rem}.pl-8{padding-left:2rem}.pt-5{padding-top:1.25rem}.pt-2{padding-top:.5rem}.pr-0{padding-right:0}.pl-5{padding-left:1.25rem}.pl-4{padding-left:1rem}.pr-7{padding-right:1.75rem}.pr-8{padding-right:2rem}.pl-6{padding-left:1.5rem}.pt-px{padding-top:1px}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.text-sm{font-size:.875rem;line-height:1.25rem}.text-lg{font-size:1.125rem}.text-lg,.text-xl{line-height:1.75rem}.text-xl{font-size:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-2xl{font-size:1.5rem;line-height:2rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-black{font-weight:900}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-5{line-height:1.25rem}.leading-relaxed{line-height:1.625}.leading-6{line-height:1.5rem}.leading-8{line-height:2rem}.leading-7{line-height:1.75rem}.leading-tight{line-height:1.25}.leading-loose{line-height:2}.leading-none{line-height:1}.leading-normal{line-height:1.5}.tracking-wider{letter-spacing:.05em}.text-theme-secondary-800{color:var(--theme-color-secondary-800)}.text-theme-success-600{color:var(--theme-color-success-600)}.text-theme-primary-500{color:var(--theme-color-primary-500)}.text-theme-secondary-900{color:var(--theme-color-secondary-900)}.text-theme-secondary-500{color:var(--theme-color-secondary-500)}.text-theme-secondary-700{color:var(--theme-color-secondary-700)}.text-theme-secondary-600{color:var(--theme-color-secondary-600)}.text-theme-warning-600{color:var(--theme-color-warning-600)}.text-theme-primary-600{color:var(--theme-color-primary-600)}.text-theme-danger-600{color:var(--theme-color-danger-600)}.text-theme-danger-400{color:var(--theme-color-danger-400)}.text-theme-secondary-400{color:var(--theme-color-secondary-400)}.text-theme-primary-300{color:var(--theme-color-primary-300)}.text-theme-secondary-300{color:var(--theme-color-secondary-300)}.text-theme-secondary-200{color:var(--theme-color-secondary-200)}.text-transparent{color:transparent}.text-theme-success-500{color:var(--theme-color-success-500)}.text-theme-danger-500{color:var(--theme-color-danger-500)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-theme-secondary-100{color:var(--theme-color-secondary-100)}.text-theme-warning-900{color:var(--theme-color-warning-900)}.text-theme-warning-200{color:var(--theme-color-warning-200)}.text-theme-primary-100{color:var(--theme-color-primary-100)}.text-theme-info-300{color:var(--theme-color-info-300)}.underline{-webkit-text-decoration-line:underline;text-decoration-line:underline}.line-through{-webkit-text-decoration-line:line-through;text-decoration-line:line-through}.no-underline{-webkit-text-decoration-line:none;text-decoration-line:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-40{opacity:.4}.opacity-75{opacity:.75}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-90{opacity:.9}.opacity-70{opacity:.7}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}.shadow-2xl,.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-navbar-dropdown{--tw-shadow:0px 15px 35px 0 rgba(33,34,37,.08);--tw-shadow-colored:0px 15px 35px 0 var(--tw-shadow-color)}.shadow-navbar-dropdown,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-0{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring,.ring-0{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.ring-focus{--tw-ring-color:rgba(var(--theme-color-primary-rgb),0.50)}.blur{--tw-blur:blur(8px)}.blur,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-xl{--tw-backdrop-blur:blur(24px)}.backdrop-blur-xl,.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-150{transition-duration:.15s}.duration-75{transition-duration:75ms}.duration-1000{transition-duration:1s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.transition-default{transition:all .1s ease-in}.fill-current{fill:currentColor}@font-face{font-family:swiper-icons;font-style:normal;font-weight:400;src:url("data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA")}:root{--swiper-theme-color:#007aff}.swiper{list-style:none;margin-left:auto;margin-right:auto;overflow:hidden;padding:0;position:relative;z-index:1}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{box-sizing:content-box;display:flex;height:100%;position:relative;transition-property:transform;width:100%;z-index:1}.swiper-android .swiper-slide,.swiper-wrapper{transform:translateZ(0)}.swiper-pointer-events{touch-action:pan-y}.swiper-pointer-events.swiper-vertical{touch-action:pan-x}.swiper-slide{flex-shrink:0;height:100%;position:relative;transition-property:transform;width:100%}.swiper-slide-invisible-blank{visibility:hidden}.swiper-autoheight,.swiper-autoheight .swiper-slide{height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;transform:translateZ(0)}.swiper-3d,.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d .swiper-slide,.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top,.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d .swiper-slide-shadow,.swiper-3d .swiper-slide-shadow-bottom,.swiper-3d .swiper-slide-shadow-left,.swiper-3d .swiper-slide-shadow-right,.swiper-3d .swiper-slide-shadow-top{height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:10}.swiper-3d .swiper-slide-shadow{background:rgba(0,0,0,.15)}.swiper-3d .swiper-slide-shadow-left{background-image:linear-gradient(270deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-right{background-image:linear-gradient(90deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-top{background-image:linear-gradient(0deg,rgba(0,0,0,.5),transparent)}.swiper-3d .swiper-slide-shadow-bottom{background-image:linear-gradient(180deg,rgba(0,0,0,.5),transparent)}.swiper-css-mode>.swiper-wrapper{-ms-overflow-style:none;overflow:auto;scrollbar-width:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode>.swiper-wrapper>.swiper-slide{scroll-snap-align:start start}.swiper-horizontal.swiper-css-mode>.swiper-wrapper{-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.swiper-vertical.swiper-css-mode>.swiper-wrapper{-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory}.swiper-centered>.swiper-wrapper:before{content:"";flex-shrink:0;order:9999}.swiper-centered.swiper-horizontal>.swiper-wrapper>.swiper-slide:first-child{-webkit-margin-start:var(--swiper-centered-offset-before);margin-inline-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-horizontal>.swiper-wrapper:before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-centered.swiper-vertical>.swiper-wrapper>.swiper-slide:first-child{-webkit-margin-before:var(--swiper-centered-offset-before);margin-block-start:var(--swiper-centered-offset-before)}.swiper-centered.swiper-vertical>.swiper-wrapper:before{height:var(--swiper-centered-offset-after);min-width:1px;width:100%}.swiper-centered>.swiper-wrapper>.swiper-slide{scroll-snap-align:center center}.swiper-virtual .swiper-slide{-webkit-backface-visibility:hidden;transform:translateZ(0)}.swiper-virtual.swiper-css-mode .swiper-wrapper:after{content:"";left:0;pointer-events:none;position:absolute;top:0}.swiper-virtual.swiper-css-mode.swiper-horizontal .swiper-wrapper:after{height:1px;width:var(--swiper-virtual-size)}.swiper-virtual.swiper-css-mode.swiper-vertical .swiper-wrapper:after{height:var(--swiper-virtual-size);width:1px}:root{--swiper-navigation-size:44px}.swiper-button-next,.swiper-button-prev{align-items:center;color:var(--swiper-navigation-color,var(--swiper-theme-color));cursor:pointer;display:flex;height:var(--swiper-navigation-size);justify-content:center;margin-top:calc(0px - var(--swiper-navigation-size)/2);position:absolute;top:50%;width:calc(var(--swiper-navigation-size)/44*27);z-index:10}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{cursor:auto;opacity:.35;pointer-events:none}.swiper-button-next.swiper-button-hidden,.swiper-button-prev.swiper-button-hidden{cursor:auto;opacity:0;pointer-events:none}.swiper-navigation-disabled .swiper-button-next,.swiper-navigation-disabled .swiper-button-prev{display:none!important}.swiper-button-next:after,.swiper-button-prev:after{font-family:swiper-icons;font-size:var(--swiper-navigation-size);font-variant:normal;letter-spacing:0;line-height:1;text-transform:none!important}.swiper-button-prev,.swiper-rtl .swiper-button-next{left:10px;right:auto}.swiper-button-prev:after,.swiper-rtl .swiper-button-next:after{content:"prev"}.swiper-button-next,.swiper-rtl .swiper-button-prev{left:auto;right:10px}.swiper-button-next:after,.swiper-rtl .swiper-button-prev:after{content:"next"}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;transform:translateZ(0);transition:opacity .3s;z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-disabled>.swiper-pagination,.swiper-pagination.swiper-pagination-disabled{display:none!important}.swiper-horizontal>.swiper-pagination-bullets,.swiper-pagination-bullets.swiper-pagination-horizontal,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{font-size:0;overflow:hidden}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{position:relative;transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active,.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{transform:scale(.33)}.swiper-pagination-bullet{background:var(--swiper-pagination-bullet-inactive-color,#000);border-radius:50%;display:inline-block;height:var(--swiper-pagination-bullet-height,var(--swiper-pagination-bullet-size,8px));opacity:var(--swiper-pagination-bullet-inactive-opacity,.2);width:var(--swiper-pagination-bullet-width,var(--swiper-pagination-bullet-size,8px))}button.swiper-pagination-bullet{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;box-shadow:none;margin:0;padding:0}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet:only-child{display:none!important}.swiper-pagination-bullet-active{background:var(--swiper-pagination-color,var(--swiper-theme-color));opacity:var(--swiper-pagination-bullet-opacity,1)}.swiper-pagination-vertical.swiper-pagination-bullets,.swiper-vertical>.swiper-pagination-bullets{right:10px;top:50%;transform:translate3d(0,-50%,0)}.swiper-pagination-vertical.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{display:block;margin:var(--swiper-pagination-bullet-vertical-gap,6px) 0}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;transform:translateY(-50%);width:8px}.swiper-pagination-vertical.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;transition:transform .2s,top .2s}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 var(--swiper-pagination-bullet-horizontal-gap,4px)}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;transform:translateX(-50%);white-space:nowrap}.swiper-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet,.swiper-pagination-horizontal.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:transform .2s,left .2s}.swiper-horizontal.swiper-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{transition:transform .2s,right .2s}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:var(--swiper-pagination-color,var(--swiper-theme-color));height:100%;left:0;position:absolute;top:0;transform:scale(0);transform-origin:left top;width:100%}.swiper-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{transform-origin:right top}.swiper-horizontal>.swiper-pagination-progressbar,.swiper-pagination-progressbar.swiper-pagination-horizontal,.swiper-pagination-progressbar.swiper-pagination-vertical.swiper-pagination-progressbar-opposite,.swiper-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{height:4px;left:0;top:0;width:100%}.swiper-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite,.swiper-pagination-progressbar.swiper-pagination-vertical,.swiper-vertical>.swiper-pagination-progressbar{height:100%;left:0;top:0;width:4px}.swiper-pagination-lock{display:none}.swiper-scrollbar{background:rgba(0,0,0,.1);border-radius:10px;position:relative;-ms-touch-action:none}.swiper-scrollbar-disabled>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-disabled{display:none!important}.swiper-horizontal>.swiper-scrollbar,.swiper-scrollbar.swiper-scrollbar-horizontal{bottom:3px;height:5px;left:1%;position:absolute;width:98%;z-index:50}.swiper-scrollbar.swiper-scrollbar-vertical,.swiper-vertical>.swiper-scrollbar{height:98%;position:absolute;right:3px;top:1%;width:5px;z-index:50}.swiper-scrollbar-drag{background:rgba(0,0,0,.5);border-radius:10px;height:100%;left:0;position:relative;top:0;width:100%}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{align-items:center;display:flex;height:100%;justify-content:center;text-align:center;width:100%}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain}.swiper-slide-zoomed{cursor:move}.swiper-lazy-preloader{border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top:4px solid transparent;box-sizing:border-box;height:42px;left:50%;margin-left:-21px;margin-top:-21px;position:absolute;top:50%;transform-origin:50%;width:42px;z-index:10}.swiper-watch-progress .swiper-slide-visible .swiper-lazy-preloader,.swiper:not(.swiper-watch-progress) .swiper-lazy-preloader{-webkit-animation:swiper-preloader-spin 1s linear infinite;animation:swiper-preloader-spin 1s linear infinite}.swiper-lazy-preloader-white{--swiper-preloader-color:#fff}.swiper-lazy-preloader-black{--swiper-preloader-color:#000}@-webkit-keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.swiper .swiper-notification{left:0;opacity:0;pointer-events:none;position:absolute;top:0;z-index:-1000}.swiper-free-mode>.swiper-wrapper{margin:0 auto;transition-timing-function:ease-out}.swiper-grid>.swiper-wrapper{flex-wrap:wrap}.swiper-grid-column>.swiper-wrapper{flex-direction:column;flex-wrap:wrap}.swiper-fade.swiper-free-mode .swiper-slide{transition-timing-function:ease-out}.swiper-fade .swiper-slide{pointer-events:none;transition-property:opacity}.swiper-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-fade .swiper-slide-active,.swiper-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube{overflow:visible}.swiper-cube .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;height:100%;pointer-events:none;transform-origin:0 0;visibility:hidden;width:100%;z-index:1}.swiper-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-cube.swiper-rtl .swiper-slide{transform-origin:100% 0}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-cube .swiper-slide-active,.swiper-cube .swiper-slide-next,.swiper-cube .swiper-slide-next+.swiper-slide,.swiper-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-cube .swiper-slide-shadow-bottom,.swiper-cube .swiper-slide-shadow-left,.swiper-cube .swiper-slide-shadow-right,.swiper-cube .swiper-slide-shadow-top{-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:0}.swiper-cube .swiper-cube-shadow{bottom:0;height:100%;left:0;opacity:.6;position:absolute;width:100%;z-index:0}.swiper-cube .swiper-cube-shadow:before{background:#000;bottom:0;content:"";filter:blur(50px);left:0;position:absolute;right:0;top:0}.swiper-flip{overflow:visible}.swiper-flip .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;pointer-events:none;z-index:1}.swiper-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-flip .swiper-slide-active,.swiper-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-flip .swiper-slide-shadow-bottom,.swiper-flip .swiper-slide-shadow-left,.swiper-flip .swiper-slide-shadow-right,.swiper-flip .swiper-slide-shadow-top{-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:0}.swiper-creative .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;transition-property:transform,opacity,height}.swiper-cards{overflow:visible}.swiper-cards .swiper-slide{-webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden;transform-origin:center bottom}.form-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-radius:.25rem;border-width:1px;font-size:1rem;line-height:1.5;padding:.5rem .75rem}.form-input::-moz-placeholder{color:#a0aec0;opacity:1}.form-input:-ms-input-placeholder{color:#a0aec0;opacity:1}.form-input::placeholder{color:#a0aec0;opacity:1}.form-select{-webkit-print-color-adjust:exact;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0'%3E%3Cpath d='M15.3 9.3a1 1 0 0 1 1.4 1.4l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 0 1 1.4-1.4l3.3 3.29 3.3-3.3z'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;border-color:#e2e8f0;border-radius:.25rem;border-width:1px;color-adjust:exact;font-size:1rem;line-height:1.5;padding:.5rem 2.5rem .5rem .75rem}.form-select::-ms-expand{border:none;color:#a0aec0}@media not print{.form-select::-ms-expand{display:none}}@media print and (-ms-high-contrast:active),print and (-ms-high-contrast:none){.form-select{padding-right:.75rem}}.form-checkbox{-webkit-print-color-adjust:exact;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#e2e8f0;border-radius:.25rem;border-width:1px;color:#4299e1;color-adjust:exact;display:inline-block;flex-shrink:0;height:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;width:1em}.form-checkbox:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.707 7.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4a1 1 0 0 0-1.414-1.414L7 8.586 5.707 7.293z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}@media not print{.form-checkbox::-ms-check{background:inherit;border-color:inherit;border-radius:inherit;border-width:1px;color:transparent}}.form-radio{-webkit-print-color-adjust:exact;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#e2e8f0;border-radius:100%;border-width:1px;color:#4299e1;color-adjust:exact;display:inline-block;flex-shrink:0;height:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;width:1em}.form-radio:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}@media not print{.form-radio::-ms-check{background:inherit;border-color:inherit;border-radius:inherit;border-width:1px;color:transparent}}.animation-spin{-webkit-animation-duration:2s;-moz-animation-duration:2s;-ms-animation-duration:2s;animation-duration:2s;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:spin;-moz-animation-name:spin;-ms-animation-name:spin;animation-name:spin;-webkit-animation-timing-function:linear;-moz-animation-timing-function:linear;-ms-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes wobble{0%{transform:translateZ(0)}15%{transform:translate3d(-25%,0,0) rotate(-5deg)}30%{transform:translate3d(20%,0,0) rotate(3deg)}45%{transform:translate3d(-15%,0,0) rotate(-3deg)}60%{transform:translate3d(10%,0,0) rotate(2deg)}75%{transform:translate3d(-5%,0,0) rotate(-1deg)}to{transform:translateZ(0)}}@keyframes wobble{0%{transform:translateZ(0)}15%{transform:translate3d(-25%,0,0) rotate(-5deg)}30%{transform:translate3d(20%,0,0) rotate(3deg)}45%{transform:translate3d(-15%,0,0) rotate(-3deg)}60%{transform:translate3d(10%,0,0) rotate(2deg)}75%{transform:translate3d(-5%,0,0) rotate(-1deg)}to{transform:translateZ(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.dropdown-button-outline{background-color:transparent;border:1px solid var(--theme-color-secondary-200);border-radius:.25rem}.dropdown-entry,.rich-select-dropdown-entry{cursor:pointer;display:block;font-weight:500;padding:1rem 2rem;text-align:left;transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);white-space:nowrap;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.dropdown-entry)>div.table-cell-content,.table-container table>tbody>tr>td.hoverable-cell:is(.rich-select-dropdown-entry)>div.table-cell-content{justify-content:flex-start}.dropdown-entry,.rich-select-dropdown-entry:not(.rich-select-dropdown-entry-selected):not(.rich-select-dropdown-entry-hover){--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));color:var(--theme-color-secondary-900)}.dark .dropdown-entry,.dark +.rich-select-dropdown-entry:not(.rich-select-dropdown-entry-selected):not(.rich-select-dropdown-entry-hover){background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.dropdown-entry:focus{outline:2px solid transparent;outline-offset:2px}.dropdown-entry:not([disabled]):not(.dropdown-entry-disabled):hover,.rich-select-dropdown-entry-hover{background-color:var(--theme-color-secondary-100);color:var(--theme-color-secondary-900)}.dark .dropdown-entry:not([disabled]):not(.dropdown-entry-disabled):hover,.dark +.rich-select-dropdown-entry-hover{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-200)}.dropdown-entry-disabled,.dropdown-entry[disabled]{cursor:not-allowed;opacity:.5}.dropdown-entry-selected,.rich-select-dropdown-entry-selected{color:var(--theme-color-primary-600);position:relative}.dark .dropdown-entry-selected,.dark +.rich-select-dropdown-entry-selected{--tw-bg-opacity:1;background-color:rgb(18 18 19/var(--tw-bg-opacity));color:var(--theme-color-primary-600)}.dropdown-entry-selected:before,.rich-select-dropdown-entry-selected:before{background-color:var(--theme-color-primary-600);content:"";height:100%;left:0;position:absolute;top:0;width:.25rem}.dropdown-entry-selected,.rich-select-dropdown-entry-selected{background-color:var(--theme-color-primary-50)}.custom-scroll::-webkit-scrollbar{border-radius:.5rem;height:4px;width:6px}.custom-scroll::-webkit-scrollbar-track-piece:start{background:transparent}.custom-scroll::-webkit-scrollbar-thumb{background-color:var(--theme-color-primary-200);border-radius:.5rem}.custom-scroll{scrollbar-color:#bad6f0 transparent}.documentation-sidebar .tabs+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.tabs{background-color:var(--theme-color-secondary-100);border-radius:.75rem;display:flex;font-weight:600}.dark .tabs{--tw-bg-opacity:1;background-color:rgb(18 18 19/var(--tw-bg-opacity))}.tab-item{border-bottom-width:3px;border-color:transparent;color:var(--theme-color-secondary-700);font-weight:600;margin-left:1.5rem;margin-right:1.5rem;padding-bottom:.75rem;padding-top:1rem;position:relative;transition:all .1s ease-in;white-space:nowrap}.tab-item-current,.tab-item:hover:not(:disabled){border-color:var(--theme-color-primary-600);color:var(--theme-color-secondary-900)}.tab-item:disabled{color:var(--theme-color-secondary-500)}.dark .tab-item-current,.dark .tab-item:hover:not(:disabled){color:var(--theme-color-secondary-200)}.tab-item:before{border-color:var(--theme-color-secondary-300);border-left-width:1px;content:"";height:1.5rem;left:0;margin-left:-1.5rem;position:absolute}.tabs>li[role=presentation]:first-child>.tab-item:before{border-left-width:0}.dark .tab-item:before{border-color:var(--theme-color-secondary-800)}.documentation-sidebar .tabs-wrapper+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.tabs-wrapper{align-items:center;display:flex;flex-direction:column;width:100%}[role=tablist]{padding-left:.5rem;padding-right:.5rem}[role=tabpanel]{width:100%}.info-badge{background-color:var(--theme-color-primary-100);border-radius:.75rem;font-size:.875rem;line-height:1.25rem;margin-left:.25rem;padding:2px 6px}.dark .info-badge{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-700)}.link{color:var(--theme-color-primary-600);cursor:pointer;-webkit-text-decoration-line:none;text-decoration-line:none;transition:all .1s ease-in}.simple-markdown a:is(.link):hover{text-decoration:none}.link.read-only{cursor:not-allowed}.link:hover{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.link.link-no-underline:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.link.link-no-underline:hover):hover{text-decoration:none}.link:active{color:var(--theme-color-primary-400)}.avatar-wrapper .avatar-circle{background-color:var(--theme-color-primary-100)}.avatar-wrapper:hover .avatar-circle{background-color:var(--theme-color-primary-200)}.documentation-sidebar .pagination-wrapper+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.pagination-wrapper{display:flex;flex-direction:column}.pagination-wrapper input::-webkit-inner-spin-button,.pagination-wrapper input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.pagination-wrapper input[type=number]{-moz-appearance:textfield}.documentation-sidebar .pagination-pages-mobile+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.pagination-pages-mobile{background-color:var(--theme-color-primary-100);border-radius:.25rem;display:flex;justify-content:center;margin-bottom:.75rem;padding-left:.5rem;padding-right:.5rem}.documentation-sidebar .pagination-button-mobile+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.pagination-button-mobile{display:flex;flex:1 1 0%;justify-content:center}.pagination-pages{background-color:var(--theme-color-primary-100);border-radius:.25rem;display:none;padding-left:.5rem;padding-right:.5rem}.dark .pagination-pages,.dark .pagination-pages-mobile{background-color:var(--theme-color-secondary-800)}@media screen and (min-width:450px){.pagination-wrapper{display:block}.pagination-pages-mobile{display:none}.pagination-button-mobile{flex:0 1 auto}.documentation-sidebar .pagination-pages+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.pagination-pages{display:flex}}@media screen and (max-width:451px){.pagination-form-desktop{display:none}}.modal-content,.modal-content-square{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));position:relative}@media screen and (max-width:767px){.modal-content,.modal-content-wrapper{max-width:100%!important}}@media (min-width:768px){.modal-content{border-radius:1.25rem}.modal-content,.modal-content-square{--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);margin-left:auto;margin-right:auto}}.dark .modal-content,.dark .modal-content-square{background-color:var(--theme-color-secondary-900)}.modal-close{background-color:var(--theme-color-info-100);border-radius:.25rem;color:var(--theme-color-secondary-900);height:2.75rem;margin-right:1.25rem;margin-top:1.25rem;position:absolute;right:0;top:0;transition:all .1s ease-in;width:3rem;z-index:50}.dark .modal-close{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-600)}.modal-close:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);background-color:var(--theme-color-info-300);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dark .modal-close:hover{background-color:var(--theme-color-secondary-700);color:var(--theme-color-secondary-400)}@media (min-width:1024px){.modal-content,.modal-content-square{width:100%}}.documentation-sidebar .modal-buttons+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.modal-buttons{display:flex;flex-direction:column-reverse;justify-content:flex-end}.modal-buttons>:not(:first-child){margin-bottom:.75rem}@media (min-width:640px){.modal-buttons{flex-direction:row}.modal-buttons>:not(:first-child){margin-bottom:0;margin-left:.75rem}}.documentation-sidebar .description-block+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.description-block{border-color:var(--theme-color-secondary-200);border-radius:.75rem;border-width:2px;display:flex;flex-direction:column;padding:2.5rem;transition:all .1s ease-in}.description-block-link:hover{--tw-bg-opacity:1;--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);background-color:rgb(255 255 255/var(--tw-bg-opacity));box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);cursor:pointer;transform:scale(1.02)}.description-block-link:hover .link{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.documentation-sidebar .navbar-mobile-link+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.navbar-mobile-link{--tw-border-opacity:1;align-items:center;border-color:rgb(255 255 255/var(--tw-border-opacity));border-left-width:3px;display:block;display:flex;font-weight:600;padding-bottom:.75rem;padding-left:2rem;padding-top:.75rem;width:100%}.dark .navbar-mobile-link{border-color:var(--theme-color-secondary-900)}.navbar-mobile-link-current{background-color:var(--theme-color-primary-100);border-color:var(--theme-color-primary-600)}.dark .navbar-mobile-link-current{background-color:var(--theme-color-secondary-800);border-color:var(--theme-color-primary-600);color:var(--theme-color-secondary-200)}.navbar-mobile-link:not(.navbar-mobile-link-current){color:var(--theme-color-secondary-900)}.navbar-mobile-link:not(.navbar-mobile-link-current):hover{color:var(--theme-color-primary-600)}.dark .navbar-mobile-link:not(.navbar-mobile-link-current){color:var(--theme-color-secondary-200)}.documentation-sidebar .circled-icon+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.circled-icon{align-items:center;border-radius:9999px;border-width:2px;display:flex;height:2.75rem;justify-content:center;width:2.75rem}.tile-selection-list{display:grid;gap:1.25rem;grid-template-columns:repeat(2,minmax(0,1fr))}.swiper-wrapper.tile-selection-list .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.grid.tile-selection-list .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.tile-selection-list .swiper-slide:nth-child(n+5),.swiper-wrapper.tile-selection-list.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.tile-selection-list.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper.tile-selection-list.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper.tile-selection-list.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:640px){.tile-selection-list{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:1024px){.tile-selection-list{grid-template-columns:repeat(6,minmax(0,1fr))}}@media (min-width:1280px){.tile-selection-list{grid-template-columns:repeat(8,minmax(0,1fr))}}.tile-selection-list-single{display:grid;gap:1.25rem;grid-template-columns:repeat(2,minmax(0,1fr))}.swiper-wrapper.tile-selection-list-single .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.grid.tile-selection-list-single .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.tile-selection-list-single .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list-single.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.tile-selection-list-single.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list-single.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list-single.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list-single.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-selection-list-single.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:640px){.tile-selection-list-single{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width:1024px){.tile-selection-list-single{grid-template-columns:repeat(5,minmax(0,1fr))}}@media (min-width:1280px){.tile-selection-list-single{grid-template-columns:repeat(6,minmax(0,1fr))}}.tile-selection-option{border-color:var(--theme-color-primary-100);border-radius:.75rem;border-width:2px;cursor:pointer;height:7.5rem;position:relative;transition:all .1s ease-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dark .tile-selection-option{border-color:var(--theme-color-secondary-800)}.tile-selection-single{border-color:var(--theme-color-primary-100);border-radius:.75rem;border-width:2px;cursor:pointer;outline:2px solid transparent;outline-offset:2px;padding-bottom:1rem;padding-top:1rem;position:relative;transition:all .1s ease-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.tile-selection-single:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-color:var(--theme-color-primary-500);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.dark .tile-selection-single{border-color:var(--theme-color-secondary-800)}.tile-selection-option:hover,.tile-selection-single:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-700)}.tile-selection-option:not(.tile-selection--checked):hover,.tile-selection-single:not(.tile-selection--checked):hover{border-color:transparent}.dark .tile-selection-option:not(.tile-selection--checked):hover,.dark +.tile-selection-single:not(.tile-selection--checked):hover{border-color:var(--theme-color-success-400)}.documentation-sidebar .tile-selection-select-all+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.tile-selection-select-all{align-items:center;display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@media (min-width:768px){.tile-selection-select-all{flex-direction:row-reverse}}.tile-selection-checkbox,.tile-selection-checkbox:focus,.tile-selection-select-all-checkbox,.tile-selection-select-all-checkbox:focus{border-color:var(--theme-color-primary-100);border-radius:.25rem;border-width:2px}.dark .tile-selection-checkbox,.dark +.tile-selection-checkbox:focus,.dark +.tile-selection-select-all-checkbox,.dark +.tile-selection-select-all-checkbox:focus{background-color:transparent;border-color:var(--theme-color-secondary-600)}.dark .group:hover .tile-selection-checkbox,.dark .group:hover +.tile-selection-checkbox:focus,.dark .group:hover +.tile-selection-select-all-checkbox,.dark .group:hover +.tile-selection-select-all-checkbox:focus{border-color:var(--theme-color-success-600)}.tile-selection-select-all-checkbox{margin-right:.5rem}@media (min-width:768px){.tile-selection-select-all-checkbox{margin-left:.5rem;margin-right:0}}.tile-selection-checkbox{cursor:pointer;position:absolute;right:.5rem;top:.5rem}.tile-selection-checkbox,.tile-selection-checkbox:focus{border-color:var(--theme-color-primary-100)}.tile-selection--checked{background-color:var(--theme-color-success-50);border-color:var(--theme-color-success-500)}.dark .tile-selection--checked{background-color:var(--theme-color-success-900);border-color:var(--theme-color-success-600);color:var(--theme-color-secondary-200)}.dark +.tile-selection-checkbox:checked,.dark .tile-selection-select-all-checkbox:checked,.tile-selection-checkbox:checked,.tile-selection-select-all-checkbox:checked{background-color:var(--theme-color-success-600);border-color:var(--theme-color-success-600)}.tile-links-list,.tile-links-list-md{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.swiper-wrapper +.tile-links-list-md .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.grid +.tile-links-list-md .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.tile-links-list .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-4 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid +.tile-links-list-md .swiper-slide:nth-child(n+4),.swiper-wrapper.grid.tile-links-list .swiper-slide:nth-child(n+4),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper +.tile-links-list-md.sm\:grid-cols-4 .swiper-slide:nth-child(n+5),.swiper-wrapper.tile-links-list.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.grid +.tile-links-list-md .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.tile-links-list .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-4 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid +.tile-links-list-md .swiper-slide:nth-child(n+5),.swiper-wrapper.grid.tile-links-list .swiper-slide:nth-child(n+5),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper +.tile-links-list-md.md\:grid-cols-4 .swiper-slide:nth-child(n+5),.swiper-wrapper.tile-links-list.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-4 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper +.tile-links-list-md.lg\:grid-cols-4 .swiper-slide:nth-child(n+5),.swiper-wrapper.tile-links-list.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-4 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper +.tile-links-list-md.xl\:grid-cols-4 .swiper-slide:nth-child(n+5),.swiper-wrapper.tile-links-list.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:640px){.tile-links-list,.tile-links-list-md{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width:768px){.tile-links-list,.tile-links-list-md{grid-template-columns:repeat(4,minmax(0,1fr))}}.tile-links-list{gap:1.25rem}@media (min-width:1024px){.tile-links-list{grid-template-columns:repeat(5,minmax(0,1fr))}}@media (min-width:1280px){.tile-links-list{grid-template-columns:repeat(6,minmax(0,1fr))}}.tile-links-list-md{gap:.75rem}.tile-links-list-sm{display:grid;gap:.75rem;grid-template-columns:repeat(3,minmax(0,1fr))}.swiper-wrapper.tile-links-list-sm .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list-sm.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.tile-links-list-sm.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-links-list-sm.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list-sm.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list-sm.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.tile-links-list-sm.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}.tile-link{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:.75rem;cursor:pointer;height:7.5rem;position:relative;transition:all .1s ease-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dark .tile-link{background-color:var(--theme-color-secondary-900)}.tile-link:not(.tile-link-disabled){cursor:pointer}.tile-link:not(.tile-links-show-more){color:var(--theme-color-secondary-900)}.tile-link:not(.tile-link-disabled):hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);border-color:transparent;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-primary-700)}.documentation-sidebar .tile-link-title-icon+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.tile-link-title-icon{align-items:center;display:flex;flex-direction:column;font-weight:600;height:100%;justify-content:center}.tile-link-sm .tile-link-title-icon{flex-direction:row}.tile-link-icon{transition:all .1s ease-in}.tile-link-icon:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark .tile-link-icon{color:var(--theme-color-secondary-600)}.dark .group:hover .tile-link-icon,.dark .tile-link-title{color:var(--theme-color-secondary-200)}.tile-links-show-more{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:.75rem;color:var(--theme-color-primary-600);cursor:pointer;font-weight:600;height:7.5rem;position:relative;text-align:center;transition:all .1s ease-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dark .tile-links-show-more{background-color:var(--theme-color-secondary-900)}.tile-links-show-more:not(.tile-link-disabled){cursor:pointer}.tile-links-show-more:not(.tile-links-show-more){color:var(--theme-color-secondary-900)}.tile-links-show-more:not(.tile-link-disabled):hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);border-color:transparent;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-primary-700)}.tile-links-show-more:hover{--tw-text-opacity:1;background-color:var(--theme-color-primary-700);color:rgb(255 255 255/var(--tw-text-opacity))}.tile-link-border{border-color:var(--theme-color-primary-100);border-width:2px}.dark .tile-link-border{border-color:var(--theme-color-secondary-800)}.tile-link-md,.tile-link-sm{font-size:.875rem;height:3rem;line-height:1.25rem}.tile-link-md .tile-link-icon,.tile-link-sm .tile-link-title{display:none}@media (min-width:640px){.tile-link-sm .tile-link-title{display:block}.tile-link-sm .tile-link-icon{display:none}.tile-link-md,.tile-link-sm{font-size:1rem;height:3.25rem;line-height:1.5rem}}@media (min-width:768px){.tile-link-md{height:5.5rem}.tile-link-sm .tile-link-icon{display:block;margin-right:.5rem}.tile-link-md .tile-link-icon{display:block;margin-bottom:.5rem}}.disabled-tile{background-color:transparent;border-color:var(--theme-color-secondary-300);opacity:.5;pointer-events:none}.tile-link-disabled:not(.tile-links-show-more){color:var(--theme-color-secondary-500)}.dark .tile-link-disabled:not(.tile-links-show-more){color:var(--theme-color-secondary-700)}.tile-link-disabled.tile-link-border{border-color:var(--theme-color-secondary-200)}.dark .tile-link-disabled.tile-link-border{border-color:var(--theme-color-secondary-800)}.dark .tile-link-disabled .tile-link-title{color:var(--theme-color-secondary-700)}.dark .tile-link-disabled .tile-link-icon{color:var(--theme-color-secondary-800)}.contact-header{padding-bottom:2rem;padding-top:2rem}.documentation-sidebar .contact-header+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.contact-header{display:flex;margin-left:auto;margin-right:auto;padding-left:2rem;padding-right:2rem}@media (min-width:768px){.contact-header{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width:1024px){.contact-header{max-width:80rem}}.contact-content{padding-bottom:2rem;padding-top:2rem}.documentation-sidebar .contact-content+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.contact-content{display:flex;margin-left:auto;margin-right:auto;padding-left:2rem;padding-right:2rem}@media (min-width:768px){.contact-content{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width:1024px){.contact-content{max-width:80rem}}.accordion{margin-left:-2rem;margin-right:-2rem}.documentation-sidebar .accordion-trigger+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.accordion-trigger{align-items:center;border-radius:.25rem;display:flex;justify-content:space-between;text-align:left;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.accordion-trigger)>div.table-cell-content{justify-content:flex-start}@media (min-width:768px){.accordion{margin-left:0;margin-right:0}.accordion+.accordion{margin-top:1rem}}.notification-dot{border-radius:9999px;display:block;position:absolute}.sidebar-group{padding-left:2rem;padding-right:2rem}@media (min-width:1024px){.sidebar-group{margin-left:1.5rem;padding-left:0;padding-right:0}}.sidebar-link+.sidebar-group>button{border-top-width:0}.documentation-sidebar .sidebar-link+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.sidebar-link{align-items:center;display:flex}.sidebar-link:last-child .sidebar-link-divider{display:none}.documentation-sidebar .twitter-embed-wrapper+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.twitter-embed-wrapper{align-items:center;display:flex;flex-direction:column}.dark .twitter-embed-wrapper,.twitter-embed-wrapper.twitter-embed-wrapper-dark{display:none}.dark .twitter-embed-wrapper.twitter-embed-wrapper-dark{display:flex}.documentation-sidebar .dark .twitter-embed-wrapper.twitter-embed-wrapper-dark+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}html{font-family:Inter,sans-serif}@supports (font-variation-settings:normal){html{font-family:Inter var,sans-serif}}.semibold{font-family:Inter Semibold}@font-face{font-display:swap;font-family:FiraMono;font-weight:400;src:url(../fonts/FiraMono-Regular.otf)}@font-face{font-display:swap;font-family:FiraMono;font-style:italic;font-weight:400;src:url(../fonts/FiraMono-RegularItalic.otf)}@font-face{font-display:swap;font-family:FiraMono;font-weight:700;src:url(../fonts/FiraMono-Bold.otf)}input[type=password]::-ms-reveal{display:none}.documentation-sidebar .input-label+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.input-label{color:var(--theme-color-secondary-700);display:flex;font-size:.875rem;font-weight:600;line-height:1.25rem;transition:all .1s ease-in}.dark .input-label{color:var(--theme-color-secondary-500)}.input-label--toggle{color:var(--theme-color-secondary-700);font-size:1rem;font-weight:600;line-height:1.25rem;margin-right:.75rem;transition:all .1s ease-in}.input-wrapper{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);border-radius:.25rem;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-900);margin-top:.5rem;position:relative}.dark .input-wrapper{color:var(--theme-color-secondary-200)}.documentation-sidebar .input-tooltip+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.input-tooltip{--tw-text-opacity:1;align-items:center;background-color:var(--theme-color-secondary-700);border-radius:9999px;color:rgb(255 255 255/var(--tw-text-opacity));display:flex;font-size:.875rem;height:1rem;justify-content:center;line-height:1.25rem;margin-left:.5rem;width:1rem}.input-text{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-radius:.25rem;border-width:1px;display:block;font-size:1rem;line-height:1.5;margin-right:1.5rem;padding:.5rem .75rem;transition:all .1s ease-in;width:100%}.input-text::-moz-placeholder{color:#a0aec0;opacity:1}.input-text:-ms-input-placeholder{color:#a0aec0;opacity:1}.input-text::placeholder{color:#a0aec0;opacity:1}.input-rich-select .input-text{padding:.75rem 1rem}.input-text{padding:.75rem 1rem}.dark :not(.light).input-text{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-700)}.input-text.shifted{padding:.75rem 3.25rem .75rem .75rem}.dark .input-text-with-prefix::-moz-placeholder,.dark .input-text-with-suffix::-moz-placeholder,.dark .input-text::-moz-placeholder{color:var(--theme-color-secondary-700)}.dark .input-text-with-prefix:-ms-input-placeholder,.dark .input-text-with-suffix:-ms-input-placeholder,.dark .input-text:-ms-input-placeholder{color:var(--theme-color-secondary-700)}.dark .input-text-with-prefix::placeholder,.dark .input-text-with-suffix::placeholder,.dark .input-text::placeholder{color:var(--theme-color-secondary-700)}.input-rich-select .form-input{padding:.75rem 1rem}.input-group:focus-within .input-label,.input-group:hover .input-label{color:var(--theme-color-primary-600)}.input-group:focus-within .form-select,.input-group:focus-within .input-text,.input-group:focus-within .input-wrapper-with-prefix,.input-group:focus-within .input-wrapper-with-suffix{border-color:var(--theme-color-primary-600)}.input-group:focus-within .input-text-with-icon:-moz-read-only,.input-group:focus-within .input-text-with-prefix:-moz-read-only,.input-group:focus-within .input-text-with-suffix:-moz-read-only,.input-group:focus-within .input-text:-moz-read-only,.input-text-with-icon:-moz-read-only,.input-text-with-prefix:-moz-read-only,.input-text-with-suffix:-moz-read-only,.input-text:-moz-read-only{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-400);cursor:not-allowed}.input-group:focus-within .input-text-with-icon:read-only,.input-group:focus-within .input-text-with-prefix:read-only,.input-group:focus-within .input-text-with-suffix:read-only,.input-group:focus-within .input-text:read-only,.input-text-with-icon:read-only,.input-text-with-prefix:read-only,.input-text-with-suffix:read-only,.input-text:read-only{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-400);cursor:not-allowed}.dark +.input-group:focus-within .input-text-with-icon:-moz-read-only,.dark .input-group:focus-within .input-text-with-prefix:-moz-read-only,.dark +.input-group:focus-within .input-text-with-suffix:-moz-read-only,.dark +.input-group:focus-within .input-text:-moz-read-only,.dark +.input-text-with-icon:-moz-read-only,.dark +.input-text-with-prefix:-moz-read-only,.dark +.input-text-with-suffix:-moz-read-only,.dark +.input-text:-moz-read-only{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-500)}.dark +.input-group:focus-within .input-text-with-icon:read-only,.dark .input-group:focus-within .input-text-with-prefix:read-only,.dark +.input-group:focus-within .input-text-with-suffix:read-only,.dark +.input-group:focus-within .input-text:read-only,.dark +.input-text-with-icon:read-only,.dark +.input-text-with-prefix:read-only,.dark +.input-text-with-suffix:read-only,.dark +.input-text:read-only{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-500)}.input-group:focus-within .input-text-with-icon.cursor-default:-moz-read-only,.input-group:focus-within .input-text-with-prefix.cursor-default:-moz-read-only,.input-group:focus-within .input-text-with-suffix.cursor-default:-moz-read-only,.input-group:focus-within .input-text.cursor-default:-moz-read-only,.input-text-with-icon.cursor-default:-moz-read-only,.input-text-with-prefix.cursor-default:-moz-read-only,.input-text-with-suffix.cursor-default:-moz-read-only,.input-text.cursor-default:-moz-read-only{cursor:default}.input-group:focus-within .input-text-with-icon.cursor-default:read-only,.input-group:focus-within .input-text-with-prefix.cursor-default:read-only,.input-group:focus-within .input-text-with-suffix.cursor-default:read-only,.input-group:focus-within .input-text.cursor-default:read-only,.input-text-with-icon.cursor-default:read-only,.input-text-with-prefix.cursor-default:read-only,.input-text-with-suffix.cursor-default:read-only,.input-text.cursor-default:read-only{cursor:default}.dark .form-select{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-700);color:var(--theme-color-secondary-200)}.input-wrapper-with-icon{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-900);margin-top:.5rem;position:relative}.input-text-with-icon{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-radius:.25rem;border-width:1px;display:block;font-size:1rem;line-height:1.5;margin-right:1.5rem;padding:.5rem .75rem;transition:all .1s ease-in;width:100%}.input-text-with-icon::-moz-placeholder{color:#a0aec0;opacity:1}.input-text-with-icon:-ms-input-placeholder{color:#a0aec0;opacity:1}.input-text-with-icon::placeholder{color:#a0aec0;opacity:1}.input-rich-select .input-text-with-icon,.input-text-with-icon{padding:.75rem 1rem}.dark :not(.light).input-text-with-icon{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-700)}.input-text-with-icon.shifted{padding:.75rem 3.25rem .75rem .75rem}.dark .input-text-with-icon::-moz-placeholder{color:var(--theme-color-secondary-700)}.dark .input-text-with-icon:-ms-input-placeholder{color:var(--theme-color-secondary-700)}.dark .input-text-with-icon::placeholder{color:var(--theme-color-secondary-700)}.input-group:focus-within .input-text-with-icon{border-color:var(--theme-color-primary-600)}.input-group:focus-within .input-text-with-icon:-moz-read-only,.input-text-with-icon:-moz-read-only{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-400);cursor:not-allowed}.input-group:focus-within .input-text-with-icon:read-only,.input-text-with-icon:read-only{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-400);cursor:not-allowed}.dark +.input-group:focus-within .input-text-with-icon:-moz-read-only,.dark .input-text-with-icon:-moz-read-only{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-500)}.dark +.input-group:focus-within .input-text-with-icon:read-only,.dark .input-text-with-icon:read-only{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-500)}.input-group:focus-within .input-text-with-icon.cursor-default:-moz-read-only,.input-text-with-icon.cursor-default:-moz-read-only{cursor:default}.input-group:focus-within .input-text-with-icon.cursor-default:read-only,.input-text-with-icon.cursor-default:read-only{cursor:default}.documentation-sidebar .input-icon+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.input-icon{align-items:center;bottom:0;display:flex;position:absolute;top:0}.documentation-sidebar + +.input-prefix+h2:not(.documentation-sidebar h2:first-of-type),.documentation-sidebar .input-prefix-icon+h2:not(.documentation-sidebar h2:first-of-type),.documentation-sidebar + +.input-suffix+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.input-prefix,.input-prefix-icon,.input-suffix{align-items:center;display:flex}.input-prefix,.input-suffix{padding-left:1rem;padding-right:1rem}.input-prefix{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.input-suffix{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.input-text--error .input-suffix{margin-left:2.5rem}.input-text--error .input-suffix .input-icon{left:0;margin-left:-3.25rem;right:auto}.input-text-with-prefix,.input-text-with-suffix{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-color:var(--theme-color-danger-500);border-radius:.25rem;border-width:0;display:block;outline:2px solid transparent;outline-offset:2px;transition:all .1s ease-in;width:100%}.dark .input-text-with-prefix,.dark +.input-text-with-suffix{background-color:var(--theme-color-secondary-900)}.input-text-with-prefix,.input-text-with-suffix{padding:.75rem 1rem}.documentation-sidebar .input-wrapper-with-prefix+h2:not(.documentation-sidebar h2:first-of-type),.documentation-sidebar + +.input-wrapper-with-suffix+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.input-wrapper-with-prefix,.input-wrapper-with-suffix{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-color:var(--theme-color-secondary-300);border-radius:.25rem;border-width:1px;display:flex}.dark .input-wrapper-with-prefix,.dark +.input-wrapper-with-suffix{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-700)}.input-wrapper-with-prefix .input-prefix-icon{color:var(--theme-color-secondary-500)}.dark .input-wrapper-with-prefix .input-prefix-icon{color:var(--theme-color-secondary-700)}.input-wrapper-with-prefix--dirty .input-prefix-icon,.input-wrapper-with-prefix:focus-within .input-prefix-icon{color:var(--theme-color-primary-500)}.dark .input-wrapper-with-prefix--dirty .input-prefix-icon,.dark +.input-wrapper-with-prefix:focus-within .input-prefix-icon{color:var(--theme-color-primary-600)}.input-wrapper-with-prefix .input-prefix{border-right-width:1px}.dark .input-wrapper-with-prefix .input-prefix{border-color:var(--theme-color-secondary-700)}.input-wrapper-with-suffix .input-suffix{border-left-width:1px}.input-wrapper-with-prefix .input-prefix,.input-wrapper-with-suffix .input-suffix{border-color:var(--theme-color-secondary-300);color:var(--theme-color-secondary-500);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dark .input-wrapper-with-prefix .input-prefix,.dark +.input-wrapper-with-suffix .input-suffix{border-color:var(--theme-color-secondary-700)}.input-radio{color:var(--theme-color-success-600);height:1rem;transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);width:1rem}.input-radio[disabled]{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-300);color:var(--theme-color-secondary-300)}.input-radio:checked[disabled]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='gray' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}.form-radio:checked.radio-checkmark{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 17 13'%3E%3Cpath d='M13.9.2 6.4 7.4 2.9 4 .4 6.4l6 5.8 10-9.6L13.9.2z'/%3E%3C/svg%3E");background-origin:content-box;color:var(--theme-color-success-500);padding:2px}.input-checkbox{border-color:var(--theme-color-secondary-300);border-width:2px;color:var(--theme-color-success-600);height:1rem;transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);width:1rem}.dark .input-checkbox{background-color:transparent;border-color:var(--theme-color-secondary-800)}.dark .input-checkbox:checked{background-color:var(--theme-color-success-600);border-color:var(--theme-color-success-600)}.input-checkbox[disabled]{background-color:var(--theme-color-secondary-100);border-color:var(--theme-color-secondary-300);color:var(--theme-color-secondary-300)}.input-checkbox:checked[disabled]{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='gray' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.707 7.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4a1 1 0 0 0-1.414-1.414L7 8.586 5.707 7.293z'/%3E%3C/svg%3E")}.input-switch-button-left{--tw-translate-x:100%}.input-switch-button-left,.input-switch-button-right{background-color:var(--theme-color-primary-600);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.input-switch-button-right{--tw-translate-x:0px}.input-switch-button-left:hover,.input-switch-button-right:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.input-group:focus-within .input-label--error,.input-group:hover .input-label--error,.input-label--error{color:var(--theme-color-danger-500)}.dark .input-group:focus-within .input-label--error,.dark .input-group:hover .input-label--error,.dark .input-label--error{color:var(--theme-color-danger-400)}.input-text--error,.input-text-with-icon--error{border-color:var(--theme-color-danger-500)}.input-text--error:not(.input-wrapper-with-suffix),.input-text-with-icon--error{margin-right:0;padding-right:2.5rem}.dark .input-text--error,.dark .input-text-with-icon--error{border-color:var(--theme-color-danger-400)}.input-text--error.shifted{padding-right:6rem}.input-group:focus-within .input-text--error,.input-group:focus-within .input-text-with-icon--error,.input-text--error:focus,.input-text-with-icon--error:focus{--tw-ring-color:var(--theme-color-danger-300);border-color:var(--theme-color-danger-300)}.input-text--error::-moz-placeholder,.input-text-with-icon--error::-moz-placeholder{color:var(--theme-color-danger-300)}.input-text--error:-ms-input-placeholder,.input-text-with-icon--error:-ms-input-placeholder{color:var(--theme-color-danger-300)}.input-text--error::placeholder,.input-text-with-icon--error::placeholder{color:var(--theme-color-danger-300)}.input-help--error{color:var(--theme-color-danger-500);font-size:.875rem;line-height:1.25rem;margin-top:.5rem}.tags-input-focus{border-color:var(--theme-color-primary-600);box-shadow:0 0 0 1px var(--theme-color-primary-600)}.documentation-sidebar .taggle_list+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.taggle_list{display:flex;flex-wrap:wrap;margin-bottom:-.25rem}.taggle_list li{display:inline;font-weight:500;margin-bottom:.25rem;margin-right:.5rem;vertical-align:baseline;white-space:nowrap}.documentation-sidebar .taggle_list .taggle+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.taggle_list .taggle{align-items:center;display:flex}.taggle_list .taggle>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.taggle_list .taggle{background-color:var(--theme-color-primary-100);border-radius:.25rem;overflow:auto;padding-left:.5rem;padding-right:.25rem}.dark .taggle_list .taggle{background-color:var(--theme-color-secondary-800)}.taggle_list .taggle{padding-bottom:.25rem!important;padding-top:.25rem!important}.taggle_list .taggle .close{align-items:center;background-color:var(--theme-color-primary-200);border-radius:.25rem;color:var(--theme-color-secondary-900);cursor:pointer;font-size:1.125rem;line-height:.75rem;padding:.25rem;pointer-events:none;right:.5rem;-webkit-text-decoration-line:none;text-decoration-line:none;white-space:nowrap}.simple-markdown a:is(.taggle_list .taggle .close):hover{text-decoration:none}.dark .taggle_list .taggle .close{background-color:var(--theme-color-secondary-700)}.taggle_list .taggle:hover{padding-bottom:.5rem;padding-top:.5rem;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.taggle_list .taggle:hover>.close{opacity:1;pointer-events:auto}.taggle_list .taggle .close:hover{color:var(--theme-color-primary-600)}.dark .taggle_list .taggle .close:hover{color:var(--theme-color-secondary-200)}.taggle_placeholder{border-radius:.25rem;color:var(--theme-color-secondary-400);left:0;max-width:100%;overflow:hidden;padding:.75rem;pointer-events:none;position:absolute;text-overflow:ellipsis;top:0;white-space:nowrap}.dark .taggle_placeholder{color:var(--theme-color-secondary-700)}.taggle_input{background-color:transparent;margin-bottom:.25rem;margin-top:.25rem;max-width:100%}.taggle_sizer{margin:0;padding:0;position:absolute;top:-500px;visibility:hidden;z-index:-1}.taggle_text{color:var(--theme-color-primary-600);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dark .taggle_text{color:var(--theme-color-secondary-200)}.taggle>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.taggle{background-color:var(--theme-color-primary-100)}.dark .taggle{background-color:var(--theme-color-secondary-800)}.disabled-tags-input .tags-input-focus{border-color:var(--theme-color-secondary-200)}.dark .disabled-tags-input .tags-input-focus{border-color:var(--theme-color-secondary-800)}.disabled-tags-input .tags-input-focus{box-shadow:0 0 0 1px var(--theme-color-secondary-200)}.dark .disabled-tags-input .tags-input-focus{box-shadow:0 0 0 1px var(--theme-color-secondary-800)}.disabled-tags-input .taggle>.close{pointer-events:all}.disabled-tags-input .taggle_input,.disabled-tags-input .taggle_list,.disabled-tags-input .taggle_placeholder,.disabled-tags-input>div{background-color:var(--theme-color-secondary-100)}.dark .disabled-tags-input .taggle_input,.dark +.disabled-tags-input .taggle_list,.dark +.disabled-tags-input .taggle_placeholder,.dark +.disabled-tags-input>div{background-color:var(--theme-color-secondary-900)}.disabled-tags-input:not(.disabled-tags-input-add) .taggle_list .taggle{padding-right:.5rem}.disabled-tags-input:not(.disabled-tags-input-add) .taggle>.close{display:none}.hide-number-input-arrows input::-webkit-inner-spin-button,.hide-number-input-arrows input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.hide-number-input-arrows input[type=number]{-moz-appearance:textfield}input[type=password]::-ms-clear,input[type=password]::-ms-reveal{display:none}.documentation-sidebar .content-container+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.content-container{display:flex;margin-left:auto;margin-right:auto;padding-left:2rem;padding-right:2rem}@media (min-width:768px){.content-container{padding-left:2.5rem;padding-right:2.5rem}}@media (min-width:1024px){.content-container{max-width:80rem}}.documentation-sidebar .content-container-full-width+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.content-container-full-width{display:flex;margin-left:auto;margin-right:auto}@media (min-width:1024px){.content-container-full-width{max-width:80rem}}.navbar-container{padding-left:2rem;padding-right:2rem}@media (min-width:768px){.navbar-container{padding-left:2.5rem;padding-right:2.5rem}}h1,h2,h3,h4{color:var(--theme-color-secondary-900)}h1,h2,h3,h4{font-weight:700}.dark h1,.dark h2,.dark h3,.dark h4{color:var(--theme-color-secondary-200)}.header-1,.header-2,.header-3,.header-4{color:var(--theme-color-secondary-900);font-weight:700}.dark header-1,.dark header-2,.dark header-3,.dark header-4{color:var(--theme-color-secondary-200)}.header-1,h1{font-size:1.875rem;line-height:2.25rem;margin-bottom:.25rem}.header-2,h2{font-size:1.5rem;line-height:2rem;margin-bottom:.25rem}.header-3,.header-4,h3,h4{font-size:1.125rem;line-height:1.75rem;margin-bottom:.25rem}@media (min-width:768px){.header-1,h1{font-size:2.25rem;line-height:2.5rem;margin-bottom:.5rem}.header-2,h2{font-size:1.875rem;line-height:2.25rem}.header-3,h3{font-size:1.5rem;line-height:2rem}}.header-1,.header-2,.header-3,.header-4,h1,h2,h3,h4{line-height:1.25}a:focus,button:focus,input:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px}button,img{-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.clear-transform{transform:none}.rotate-90{transform:rotate(90deg)}.rotate-180{transform:rotate(180deg)}.rotate-minus-90{transform:rotate(-90deg)}.documentation-sidebar .image-tile+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.image-tile{align-items:center;border-color:var(--theme-color-primary-100);border-radius:.75rem;border-width:1px;display:flex;flex-direction:column;justify-content:space-between;padding:2rem;transition:all .1s ease-in}.image-tile:hover{--tw-bg-opacity:1;--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);background-color:rgb(255 255 255/var(--tw-bg-opacity));border-color:transparent;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transform:scale(1.02)}.documentation-sidebar .logo-entry+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.logo-entry{align-items:center;border-bottom-width:2px;border-color:var(--theme-color-info-100);display:flex;transition:all .1s ease-in}.logo-entry:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);border-color:transparent;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.logo-entry-image{display:block}.logo-entry-image,.logo-entry-image-hover{height:100%;position:absolute;width:100%}.logo-entry-image-hover{visibility:hidden}.logo-entry:hover .logo-entry-image-hover{visibility:visible}.logo-entry:hover .logo-entry-image{visibility:hidden}.logo-simple .logo-simple-image-hover{display:none;left:0;position:absolute;top:0}.logo-simple:hover .logo-simple-image{visibility:hidden}.logo-simple:hover .logo-simple-image-hover{display:block}.picasso circle{mix-blend-mode:soft-light}[x-cloak]{display:none}.video-container{height:0;padding-bottom:56.25%;position:relative}.video-container iframe{height:100%;left:0;position:absolute;top:0;width:100%}.avatar-letters{fill:#fff;stroke:#fff;font-size:1.75rem}.extended-footer-contact input,.extended-footer-contact textarea{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-700);color:var(--theme-color-secondary-200)}.extended-footer-contact input[readonly],.extended-footer-contact textarea[readonly]{background-color:var(--theme-color-secondary-800);border-color:var(--theme-color-secondary-700);color:var(--theme-color-secondary-700)}.extended-footer-contact button[type=submit]{--tw-text-opacity:1;background-color:var(--theme-color-primary-600);border-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}.extended-footer-contact button[type=submit]:hover{background-color:var(--theme-color-primary-700)}.extended-footer-contact button[type=submit]:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .extended-footer-contact button[type=submit]:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}a.extended-footer-contact button[type=submit]{display:inline-block}.dark .extended-footer-contact button[type=submit]:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.swiper{height:100%;margin-left:auto;margin-right:auto;width:100%}.swiper,.swiper:not(.slider-pagination-bottom){margin-top:2rem}.swiper.slider-pagination-bottom{margin-bottom:2rem;margin-top:1.25rem}.swiper:not(.slider-pagination-bottom) .swiper-wrapper{margin-bottom:2rem}.swiper .swiper-pagination{bottom:0;position:relative}.documentation-sidebar .swiper:not(.slider-pagination-bottom) .swiper-pagination+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.swiper:not(.slider-pagination-bottom) .swiper-pagination{align-items:center;display:flex}.swiper.slider-pagination-bottom .swiper-pagination{margin-top:1.25rem}@media (min-width:1280px){.swiper.slider-multirow>.swiper-wrapper{flex-wrap:wrap}}.swiper .swiper-pagination-bullets>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.swiper-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin-left:0;margin-right:0}@media (min-width:640px){.swiper.slider-show-view-all:not(.slider-pagination-bottom) .swiper-pagination-bullets .swiper-pagination-bullet:last-child{margin-right:1.5rem;position:relative}.swiper.slider-show-view-all:not(.slider-pagination-bottom) .swiper-pagination-bullets .swiper-pagination-bullet:last-child:before{background-color:var(--theme-color-secondary-300);margin-top:-.5rem;position:absolute;width:1px}.dark .swiper.slider-show-view-all:not(.slider-pagination-bottom) .swiper-pagination-bullets .swiper-pagination-bullet:last-child:before{background-color:var(--theme-color-secondary-800)}.swiper.slider-show-view-all:not(.slider-pagination-bottom) .swiper-pagination-bullets .swiper-pagination-bullet:last-child:before{content:"";height:calc(100% + 1rem);right:calc(-1.5rem - 1px)}}.swiper-button-next,.swiper-button-prev{padding-bottom:3rem}.swiper-button-next:after,.swiper-button-prev:after{font-size:1.75rem}div.swiper-button-next,div.swipwer-button-prev{color:var(--theme-color-primary-500)}span.swiper-pagination-bullet{opacity:1}.dark span.swiper-pagination-bullet{background-color:var(--theme-color-secondary-600)}span.swiper-pagination-bullet{background-color:rgba(62,157,255,.2)}span.swiper-pagination-bullet-active{background-color:var(--theme-color-primary-500)}.dark span.swiper-pagination-bullet-active{background-color:var(--theme-color-primary-600)}.slider-title{align-items:flex-end;flex:1 1 0%;margin-bottom:0;overflow:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap}.swiper-pagination-bullet:only-child,.swiper-wrapper.grid .swiper-slide:nth-child(n+2){display:none}@media (min-width:640px){.swiper-wrapper.grid.sm\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.sm\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.sm\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.sm\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.sm\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.grid.sm\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.grid.sm\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.grid.sm\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:768px){.swiper-wrapper.grid.md\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.md\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.md\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.md\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.md\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.grid.md\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.grid.md\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.grid.md\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1024px){.swiper-wrapper.grid.lg\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.lg\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.lg\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.lg\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.lg\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.grid.lg\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.grid.lg\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.grid.lg\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}@media (min-width:1280px){.swiper-wrapper.grid.xl\:grid-cols-1 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.xl\:grid-cols-2 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.xl\:grid-cols-3 .swiper-slide:nth-child(n+0),.swiper-wrapper.grid.xl\:grid-cols-4 .swiper-slide:nth-child(n+0){display:block}.swiper-wrapper.grid.xl\:grid-cols-1 .swiper-slide:nth-child(n+2),.swiper-wrapper.grid.xl\:grid-cols-2 .swiper-slide:nth-child(n+3),.swiper-wrapper.grid.xl\:grid-cols-3 .swiper-slide:nth-child(n+4),.swiper-wrapper.grid.xl\:grid-cols-4 .swiper-slide:nth-child(n+5){display:none}}.table-container table{height:100%;text-align:left;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.table-container table)>div.table-cell-content{justify-content:flex-start}.table-container table thead{color:var(--theme-color-secondary-500);font-size:.875rem;font-weight:600;line-height:1.25rem}.table-container table thead tr{border-bottom-width:1px;border-color:var(--theme-color-secondary-300);text-align:left}.table-container table>tbody>tr>td.hoverable-cell:is(.table-container table thead tr)>div.table-cell-content{justify-content:flex-start}.dark .table-container table tbody tr,.dark .table-container table thead th:not(:last-child):after,.dark .table-container table thead tr{border-color:var(--theme-color-secondary-800)}.table-container table thead th{padding:.75rem;position:relative}.table-container table thead th:after{border-color:var(--theme-color-secondary-300);border-left-width:1px;height:50%;position:absolute;right:0;top:25%}.table-container table thead th:not(:last-child):not(.last-cell):after{content:""}@media (min-width:640px){.table-container table thead th.last-cell-sm:after{content:""}}@media (min-width:768px){.table-container table thead th.last-cell-md:after{content:""}}@media (min-width:1024px){.table-container table thead th.last-cell-lg:after{content:""}}@media (min-width:1280px){.table-container table thead th.last-cell-xl:after{content:""}}.table-container table tbody td{line-height:1.25rem;padding:1rem .75rem}.table-container table tbody tr{border-bottom:1px var(--theme-color-secondary-300);border-left-color:var(--theme-color-secondary-300);border-right-color:var(--theme-color-secondary-300);border-style:dashed;border-top-color:var(--theme-color-secondary-300)}.table-container table tbody tr:last-child{border-width:0}.dark .table-container{color:var(--theme-color-secondary-500)}.documentation-sidebar .table-list-mobile-row+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.table-list-mobile-row{display:flex;flex-direction:column;width:100%}.table-list-mobile-row>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.table-list-mobile-row{border-color:var(--theme-color-secondary-300);border-top-width:1px;padding-bottom:1.5rem;padding-top:1.5rem}.table-list-mobile-row:first-child{border-top-width:0;padding-top:0}.dark .table-list-mobile-row{border-color:var(--theme-color-secondary-800)}.documentation-sidebar .table-list-mobile-row>div:not(.table-list-mobile-name)+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.table-list-mobile-row>div:not(.table-list-mobile-name){display:flex;justify-content:space-between;width:100%}.documentation-sidebar .table-list-mobile-name+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.table-list-mobile-name{align-items:center;display:flex;margin-bottom:.5rem}.table-list-mobile-name>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.table-list-mobile-name{font-size:1.125rem;line-height:1.75rem}@media (min-width:768px){.table-list-mobile{display:none}}.table-container .table-wrapper{scrollbar-color:#e5f0f8 #bad6f0}.table-container .table-wrapper::-webkit-scrollbar{background-color:var(--theme-color-primary-100);border-radius:.5rem;height:6px;width:6px}.table-container .table-wrapper::-webkit-scrollbar-thumb{background-color:var(--theme-color-primary-200);border-radius:.5rem}.table-container table tbody td.hoverable-cell{padding:.125rem 0}.table-container table tbody tr{outline:2px solid transparent;outline-offset:2px}.table-container table>tbody>tr>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell:last-child>div.table-cell-bg:before{border-bottom-width:1px;border-color:transparent;border-top-width:1px;content:"";display:block;height:100%;position:absolute;top:0;width:1rem}.table-container table>tbody>tr>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell:first-child>div.table-cell-bg:before{border-bottom-left-radius:.75rem;border-left-width:1px;border-top-left-radius:.75rem;left:0;margin-left:-1rem}.table-container table>tbody>tr>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell:last-child>div.table-cell-bg:before{border-bottom-right-radius:.75rem;border-right-width:1px;border-top-right-radius:.75rem;margin-right:-1rem;right:0}.table-container table>tbody>tr>td.hoverable-cell{position:relative}.documentation-sidebar .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{align-items:center;display:flex;padding-left:.75rem;padding-right:.75rem;position:relative}.table-container table>tbody>tr>td.hoverable-cell>div.table-cell-bg{--tw-border-opacity:1;border-bottom-width:2px;border-color:rgb(255 255 255/var(--tw-border-opacity));border-top-width:2px;height:100%;left:0;position:absolute;top:0;width:100%}.dark .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-bg{border-color:var(--theme-color-secondary-900)}.table-container table>tbody>tr>td.hoverable-cell.text-right>div.table-cell-content{justify-content:flex-end}.table-container table>tbody>tr>td.hoverable-cell:is(.text-left)>div.table-cell-content{justify-content:flex-start}.table-container table>tbody>tr>td.hoverable-cell>div.table-cell-bg:after{border-bottom-width:1px;border-color:transparent;border-top-width:1px;bottom:0;content:"";height:100%;left:0;pointer-events:none;position:absolute;right:0;top:0;width:100%}.table-container table>tbody>tr:focus>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr:focus>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr:focus>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr:focus>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr:focus>td.hoverable-cell>div.table-cell-bg,.table-container table>tbody>tr:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr:hover>td.hoverable-cell>div.table-cell-bg{background-color:var(--theme-color-secondary-100)}.table-container table>tbody>tr[data-danger]:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-danger]:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-danger]:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-danger]:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-danger]:hover>td.hoverable-cell>div.table-cell-bg{background-color:var(--theme-color-danger-100)}.table-container table>tbody>tr[data-warning]:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-warning]:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-warning]:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-warning]:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-warning]:hover>td.hoverable-cell>div.table-cell-bg{background-color:var(--theme-color-warning-100)}.table-container table>tbody>tr[data-info]:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-info]:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-info]:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-info]:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-info]:hover>td.hoverable-cell>div.table-cell-bg{background-color:var(--theme-color-info-100)}.table-container table>tbody>tr[data-success]:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-success]:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.table-container table>tbody>tr[data-success]:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-success]:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.table-container table>tbody>tr[data-success]:hover>td.hoverable-cell>div.table-cell-bg{background-color:var(--theme-color-success-100)}.dark .table-container table>tbody>tr:hover>td.hoverable-cell.first-cell>div.table-cell-bg:before,.dark .table-container table>tbody>tr:hover>td.hoverable-cell.last-cell>div.table-cell-bg:before,.dark .table-container table>tbody>tr:hover>td.hoverable-cell:first-child>div.table-cell-bg:before,.dark .table-container table>tbody>tr:hover>td.hoverable-cell:last-child>div.table-cell-bg:before,.dark .table-container table>tbody>tr:hover>td.hoverable-cell>div.table-cell-bg{--tw-bg-opacity:1!important;background-color:rgb(18 18 19/var(--tw-bg-opacity))!important}.table-container table tbody td.hoverable-cell:last-child .table-cell-content,.table-container table thead th.last-until-lg,.table-container table thead th.last-until-md,.table-container table thead th.last-until-sm,.table-container table thead th.last-until-xl,.table-container table thead th:last-child{padding-right:0}.table-container table tbody td.hoverable-cell:first-child .table-cell-content,.table-container table thead th:first-child{padding-left:0}@media (min-width:640px){.table-container table>tbody>tr>td.hoverable-cell.first-cell-sm>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell.last-cell-sm>div.table-cell-bg:before{content:none}.table-container table thead th.last-until-sm{padding-right:.75rem}}@media (min-width:768px){.table-container table>tbody>tr>td.hoverable-cell.first-cell-md>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell.last-cell-md>div.table-cell-bg:before{content:none}.table-container table thead th.last-until-md{padding-right:.75rem}}@media (min-width:1024px){.table-container table>tbody>tr>td.hoverable-cell.first-cell-lg>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell.last-cell-lg>div.table-cell-bg:before{content:none}.table-container table thead th.last-until-lg{padding-right:.75rem}}@media (min-width:1280px){.table-container table>tbody>tr>td.hoverable-cell.first-cell-xl>div.table-cell-bg:before,.table-container table>tbody>tr>td.hoverable-cell.last-cell-xl>div.table-cell-bg:before{content:none}.table-container table thead th.last-until-xl{padding-right:.75rem}}.table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg,.table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg:before{background-color:var(--theme-color-warning-50)}.table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg,.table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg:before{background-color:var(--theme-color-primary-50)}.table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg,.table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg:before{background-color:var(--theme-color-success-50)}.table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg,.table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg:before{background-color:var(--theme-color-danger-50)}.dark .table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg:after,.dark .table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg:before{border-color:var(--theme-color-warning-500)}.dark .table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg:after,.dark .table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg:before{border-color:var(--theme-color-primary-600)}.dark .table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg:after,.dark .table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg:before{border-color:var(--theme-color-success-600)}.dark .table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg:after,.dark .table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg:before{border-color:var(--theme-color-danger-300)}.dark .table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg,.dark .table-container table>tbody>tr[data-danger]>td.hoverable-cell>div.table-cell-bg:before,.dark .table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg,.dark .table-container table>tbody>tr[data-info]>td.hoverable-cell>div.table-cell-bg:before,.dark .table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg,.dark .table-container table>tbody>tr[data-success]>td.hoverable-cell>div.table-cell-bg:before,.dark .table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg,.dark .table-container table>tbody>tr[data-warning]>td.hoverable-cell>div.table-cell-bg:before{background-color:transparent}.table-container table:not(.table-compact)>tbody>tr>td.hoverable-cell>div.table-cell-content,body:not(.table-compact) .table-container>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:1rem;padding-top:1rem}.table-container table.table-compact>tbody>tr>td.hoverable-cell>div.table-cell-content,body.table-compact .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:.75rem;padding-top:.75rem}@media (min-width:640px){.table-container table.table-compact.table-compact-until-sm>tbody>tr>td.hoverable-cell>div.table-cell-content,body.table-compact.table-compact-until-sm .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:1rem;padding-top:1rem}}@media (min-width:768px){.table-container table.table-compact.table-compact-until-md>tbody>tr>td.hoverable-cell>div.table-cell-content,body.table-compact.table-compact-until-md .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:1rem;padding-top:1rem}}@media (min-width:1024px){.table-container table.table-compact.table-compact-until-lg>tbody>tr>td.hoverable-cell>div.table-cell-content,body.table-compact.table-compact-until-lg .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:1rem;padding-top:1rem}}@media (min-width:1280px){.table-container table.table-compact.table-compact-until-xl>tbody>tr>td.hoverable-cell>div.table-cell-content,body.table-compact.table-compact-until-xl .table-container table>tbody>tr>td.hoverable-cell>div.table-cell-content{padding-bottom:1rem;padding-top:1rem}}.table-container table.sticky-headers th{--tw-bg-opacity:1;background-clip:padding-box;background-color:rgb(255 255 255/var(--tw-bg-opacity));box-shadow:inset 0 -1px 0 var(--theme-color-secondary-300);position:-webkit-sticky;position:sticky;z-index:5}.dark .table-container table.sticky-headers th{box-shadow:inset 0 -1px 0 var(--theme-color-secondary-800)}.table-container table.sticky-headers th.last-cell:before,.table-container table.sticky-headers th:first-child:before,.table-container table.sticky-headers th:last-child:before{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-color:var(--theme-color-secondary-300);border-width:0;content:"";height:100%;position:absolute;top:0;width:1rem}.dark .table-container table.sticky-headers th:first-child:before,.dark .table-container table.sticky-headers th:last-child:before{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-800)}.table-container table.sticky-headers th.first-cell:before,.table-container table.sticky-headers th:first-child:before{left:0;margin-left:-1rem}.table-container table.sticky-headers th.last-cell:before,.table-container table.sticky-headers th:last-child:before{margin-right:-1rem;right:0}.dark .table-container table.sticky-headers th.last-cell:before{background-color:var(--theme-color-secondary-900)}@media (min-width:1280px){.table-container table.sticky-headers th.last-cell-xl:before{border-left-width:1px;border-right-width:0;height:50%;margin-right:0;position:absolute;right:0;top:25%;width:auto}}@media (min-width:1024px){.table-container table.sticky-headers th.last-cell-lg:before{border-left-width:1px;border-right-width:0;height:50%;margin-right:0;position:absolute;right:0;top:25%;width:auto}}@media (min-width:768px){.table-container table.sticky-headers th.last-cell-md:before{border-left-width:1px;border-right-width:0;height:50%;margin-right:0;position:absolute;right:0;top:25%;width:auto}}@media (min-width:640px){.table-container table.sticky-headers th.last-cell-sm:before{border-left-width:1px;border-right-width:0;height:50%;margin-right:0;position:absolute;right:0;top:25%;width:auto}}.dark .table-container table.sticky-headers th{background-color:var(--theme-color-secondary-900)}.table-container table.sticky-headers thead tr{border-style:none}:root{--theme-color-primary-rgb:9,100,228;--theme-color-primary-50:#f5faff;--theme-color-primary-100:#e5f0f8;--theme-color-primary-200:#bad6f0;--theme-color-primary-300:#99c7ee;--theme-color-primary-400:#77b9f3;--theme-color-primary-500:#3e9dff;--theme-color-primary-600:#007dff;--theme-color-primary-700:#075af2;--theme-color-primary-800:#0b4dc7;--theme-color-primary-900:#173e85;--theme-color-secondary-50:#fcfdfd;--theme-color-secondary-100:#f7fafb;--theme-color-secondary-200:#eef3f5;--theme-color-secondary-300:#dbdee5;--theme-color-secondary-400:#c4c8cf;--theme-color-secondary-500:#a5adb9;--theme-color-secondary-600:#7e8a9c;--theme-color-secondary-700:#637282;--theme-color-secondary-800:#3c4249;--theme-color-secondary-900:#212225;--theme-color-danger-50:#fff5f2;--theme-color-danger-100:#ffe0da;--theme-color-danger-200:#feb8ae;--theme-color-danger-300:#ef7c6d;--theme-color-danger-400:#de5846;--theme-color-danger-500:#c9292c;--theme-color-danger-600:#b01e20;--theme-color-danger-700:#881a1b;--theme-color-danger-800:#5b1b1b;--theme-color-danger-900:#391919;--theme-color-warning-50:#fff8eb;--theme-color-warning-100:#ffe6b8;--theme-color-warning-200:#ffd486;--theme-color-warning-300:#ffc359;--theme-color-warning-400:#feb933;--theme-color-warning-500:#ffae10;--theme-color-warning-600:#fc9f0f;--theme-color-warning-700:#f88e0d;--theme-color-warning-800:#f27c0b;--theme-color-warning-900:#ec5c08;--theme-color-success-50:#f1fbf4;--theme-color-success-100:#e2f0e6;--theme-color-success-200:#b0dbbc;--theme-color-success-300:#8cc69d;--theme-color-success-400:#60c07c;--theme-color-success-500:#42b263;--theme-color-success-600:#289548;--theme-color-success-700:#307845;--theme-color-success-800:#2b4f35;--theme-color-success-900:#26372b;--theme-color-info-50:#f5faff;--theme-color-info-100:#e5f0f8;--theme-color-info-200:#bad6f0;--theme-color-info-300:#99c7ee;--theme-color-info-400:#77b9f3;--theme-color-info-500:#3e9dff;--theme-color-info-600:#007dff;--theme-color-info-700:#075af2;--theme-color-info-800:#0b4dc7;--theme-color-info-900:#173e85;--theme-color-hint-50:#f5f5ff;--theme-color-hint-100:#e5e5ff;--theme-color-hint-200:#d6d5ff;--theme-color-hint-300:#9c9aff;--theme-color-hint-400:#6e6cef;--theme-color-hint-500:#5b59dc;--theme-color-hint-600:#5452ce;--theme-color-hint-700:#4745b0;--theme-color-hint-800:#363383;--theme-color-hint-900:#212052;--theme-color-white:#fff}.simple-markdown{color:var(--theme-color-secondary-700);overflow-wrap:break-word}.simple-markdown p{line-height:1.75rem}.simple-markdown p+p{margin-top:0}.simple-markdown .heading-permalink{display:none}.simple-markdown ul{list-style-type:disc}.simple-markdown ol,.simple-markdown ul{list-style-position:outside;margin-bottom:0;padding-left:1rem}.simple-markdown ol{list-style-type:decimal}.simple-markdown ol ul,.simple-markdown ul ul{list-style-position:outside;list-style-type:circle;margin-bottom:0;margin-left:1rem}.simple-markdown ol ol,.simple-markdown ul ol{list-style-position:outside;list-style-type:lower-latin;margin-bottom:0;margin-left:1rem}.simple-markdown ol>li,.simple-markdown ul>li{padding-bottom:.5rem}.simple-markdown blockquote{border-left-width:2px;color:var(--theme-color-secondary-500);font-style:italic;line-height:1.75rem;padding-left:1.5rem}.simple-markdown h3{margin-top:1rem}.simple-markdown h4{margin-top:.5rem}.simple-markdown ul{margin-bottom:.5rem}.simple-markdown p{padding-bottom:.5rem}.simple-markdown a{color:var(--theme-color-primary-600);font-weight:600;-webkit-text-decoration-line:none;text-decoration-line:none;transition:all .1s ease-in}.simple-markdown a:is(.simple-markdown a):hover{text-decoration:none}.simple-markdown a[target=_blank]:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.simple-markdown a[target=_blank]:hover):hover{text-decoration:none}.simple-markdown a:hover,.simple-markdown a[target=_blank]:hover>span{-webkit-text-decoration-line:underline;text-decoration-line:underline}.simple-markdown a:hover{color:var(--theme-color-primary-700)}.simple-markdown a:is(.no-underline):hover{text-decoration:none}.simple-markdown a:active{color:var(--theme-color-primary-400)}.simple-markdown table{text-align:left;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.simple-markdown table)>div.table-cell-content{justify-content:flex-start}.simple-markdown table thead{color:var(--theme-color-secondary-500);font-size:.875rem;font-weight:600;line-height:1.25rem}.simple-markdown table thead tr{border-bottom-width:1px;border-color:var(--theme-color-secondary-300);text-align:left}.table-container table>tbody>tr>td.hoverable-cell:is(.simple-markdown table thead tr)>div.table-cell-content{justify-content:flex-start}.simple-markdown table thead th{padding:.75rem;position:relative}.simple-markdown table thead th:not(:last-child):after{border-color:var(--theme-color-secondary-300);border-left-width:1px;content:"";height:50%;position:absolute;right:0}.simple-markdown table tbody td{line-height:1.25rem;padding:1rem .75rem}.simple-markdown table tbody tr{border-bottom:1px var(--theme-color-secondary-300);border-left-color:var(--theme-color-secondary-300);border-right-color:var(--theme-color-secondary-300);border-style:dashed;border-top-color:var(--theme-color-secondary-300)}.simple-markdown table tbody tr:last-child{border-width:0}.simple-markdown .table-wrapper{scrollbar-color:#e5f0f8 #bad6f0}.simple-markdown .table-wrapper::-webkit-scrollbar{background-color:var(--theme-color-primary-100);border-radius:.5rem;height:4px;width:6px}.simple-markdown .table-wrapper::-webkit-scrollbar-track-piece:start{background:transparent}.simple-markdown .table-wrapper::-webkit-scrollbar-thumb{background-color:var(--theme-color-primary-200);border-radius:.5rem}.simple-markdown .table-wrapper{scrollbar-color:#bad6f0 transparent}.simple-markdown .cookie-policy-table tbody>tr>td:nth-of-type(3){min-width:32rem}.light-dark-icon{--icon-color-primary-100:var(--theme-color-primary-100);--icon-color-primary-200:var(--theme-color-primary-200);--icon-color-secondary-200:var(--theme-color-secondary-200);--icon-color-secondary-300:var(--theme-color-secondary-300);--icon-color-secondary-900:var(--theme-color-secondary-900);--icon-color-success-50:var(--theme-color-success-50);--icon-color-warning-100:var(--theme-color-warning-100);--icon-color-danger-100:var(--theme-color-danger-100);--icon-error-primary-100:var(--theme-color-primary-100);--icon-error-primary-600:var(--theme-color-primary-600);--icon-error-secondary-200:var(--theme-color-secondary-200);--icon-error-secondary-300:var(--theme-color-secondary-300);--icon-error-secondary-900:var(--theme-color-secondary-900)}.dark .light-dark-icon{--icon-color-primary-100:var(--theme-color-primary-900);--icon-color-primary-200:var(--theme-color-primary-900);--icon-color-secondary-200:var(--theme-color-secondary-800);--icon-color-secondary-300:var(--theme-color-secondary-800);--icon-color-secondary-900:var(--theme-color-secondary-600);--icon-color-success-50:var(--theme-color-success-800);--icon-color-warning-100:var(--theme-color-warning-900);--icon-color-danger-100:var(--theme-color-danger-800);--icon-error-primary-100:var(--theme-color-primary-900);--icon-error-primary-600:var(--theme-color-primary-600);--icon-error-secondary-300:var(--theme-color-secondary-800)}.ark-logo-red{--icon-color-secondary:#fff;color:var(--theme-color-danger-500)}.cookie-banner-theme{--cc-bg:var(--theme-color-white);--cc-btn-primary-bg:var(--theme-color-primary-600);--cc-btn-primary-text:var(--theme-color-white);--cc-btn-primary-hover-bg:var(--theme-color-primary-700);--cc-btn-secondary-bg:var(--theme-color-primary-100);--cc-btn-secondary-text:var(--theme-color-primary-600);--cc-btn-secondary-hover-bg:var(--theme-color-primary-700);--cc-btn-secondary-hover-text:var(--theme-color-white);--cc-cookie-category-block-bg:var(--theme-color-white);--cc-block-text:var(--theme-color-secondary-700);--cc-section-border:transparent;--cc-toggle-knob-bg:var(--theme-color-white);--cc-toggle-knob-icon-color:var(--theme-color-white)}.dark .cookie-banner-theme{--cc-bg:var(--theme-color-secondary-900);--cc-btn-secondary-bg:var(--theme-color-secondary-800);--cc-btn-secondary-text:var(--theme-color-secondary-200);--cc-block-text:var(--theme-color-secondary-500);--cc-cookie-table-border:var(--theme-color-secondary-800);--cc-toggle-knob-bg:var(--theme-color-secondary-600);--cc-toggle-knob-icon-color:var(--theme-color-secondary-600)}#cc--main{--cc-bg:var(--theme-color-white);--cc-btn-primary-bg:var(--theme-color-primary-600);--cc-btn-primary-text:var(--theme-color-white);--cc-btn-primary-hover-bg:var(--theme-color-primary-700);--cc-btn-secondary-bg:var(--theme-color-primary-100);--cc-btn-secondary-text:var(--theme-color-primary-600);--cc-btn-secondary-hover-bg:var(--theme-color-primary-700);--cc-btn-secondary-hover-text:var(--theme-color-white);--cc-cookie-category-block-bg:var(--theme-color-white);--cc-block-text:var(--theme-color-secondary-700);--cc-section-border:transparent;--cc-toggle-knob-bg:var(--theme-color-white);--cc-toggle-knob-icon-color:var(--theme-color-white)}.dark #cc--main{--cc-bg:var(--theme-color-secondary-900);--cc-btn-secondary-bg:var(--theme-color-secondary-800);--cc-btn-secondary-text:var(--theme-color-secondary-200);--cc-block-text:var(--theme-color-secondary-500);--cc-cookie-table-border:var(--theme-color-secondary-800);--cc-toggle-knob-bg:var(--theme-color-secondary-600);--cc-toggle-knob-icon-color:var(--theme-color-secondary-600)}.cc_div #c-bns button:last-of-type:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.cc_div #c-ttl{color:var(--theme-color-secondary-900);font-size:1.125rem;line-height:2rem}.cc_div #c-txt{font-size:.875rem;line-height:1.25rem;line-height:1.5}@media (min-width:768px){.cc_div #s-hdr #s-ttl{font-size:1.875rem;line-height:2.25rem}}.cc_div #s-hdr #s-ttl{color:var(--theme-color-secondary-900);font-size:1.5rem;font-weight:700;line-height:1.25;line-height:2rem;margin-bottom:.25rem}a.cc_div .c-bl>div a.focus-visible,a +.cc_div button.preferences-button.focus-visible,button.cc_div .c-bl>div a.focus-visible,button +.cc_div button.preferences-button.focus-visible{border-radius:.25rem}a.cc_div .c-bl>div a:focus-visible,a +.cc_div button.preferences-button:focus-visible,button.cc_div .c-bl>div a:focus-visible,button +.cc_div button.preferences-button:focus-visible{border-radius:.25rem}.cc_div .c-bl>div a,.cc_div button.preferences-button{color:var(--theme-color-primary-600);cursor:pointer;font-weight:600;-webkit-text-decoration-line:none;text-decoration-line:none;transition:all .1s ease-in}.simple-markdown a:is(.cc_div .c-bl>div a):hover,.simple-markdown a:is(.cc_div button.preferences-button):hover{text-decoration:none}.cc_div .c-bl>div a.read-only,.cc_div button.preferences-button.read-only{cursor:not-allowed}.cc_div .c-bl>div a:hover,.cc_div button.preferences-button:hover{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.cc_div .c-bl>div a.link-no-underline:hover,.cc_div button.preferences-button.link-no-underline:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.cc_div .c-bl>div a.link-no-underline:hover):hover,.simple-markdown a:is(.cc_div button.preferences-button.link-no-underline:hover):hover{text-decoration:none}.cc_div .c-bl>div a:active,.cc_div button.preferences-button:active{color:var(--theme-color-primary-400)}.description-block-link:hover .cc_div .c-bl>div a,.description-block-link:hover +.cc_div button.preferences-button{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.cc_div #s-bns #s-all-bn{--tw-text-opacity:1;background-color:var(--theme-color-primary-600);border-radius:.25rem;color:rgb(255 255 255/var(--tw-text-opacity));font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}.cc_div #s-bns #s-all-bn:hover{background-color:var(--theme-color-primary-700)}.cc_div #s-bns #s-all-bn:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .cc_div #s-bns #s-all-bn:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}a.cc_div #s-bns #s-all-bn{display:inline-block}.cc_div #s-bns #s-rall-bn:disabled,.cc_div #s-bns #s-sv-bn:disabled,.dark .cc_div #s-bns #s-all-bn:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.cc_div #s-bns #s-rall-bn:disabled,.cc_div #s-bns #s-sv-bn:disabled{background-color:var(--theme-color-secondary-200);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .cc_div #s-bns #s-rall-bn:disabled,.dark +.cc_div #s-bns #s-sv-bn:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.cc_div #s-bns #s-rall-bn,.cc_div #s-bns #s-sv-bn{background-color:var(--theme-color-primary-100);border-radius:.25rem;color:var(--theme-color-primary-600);font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}.dark .cc_div #s-bns #s-rall-bn,.dark .cc_div #s-bns #s-rall-bn:hover,.dark +.cc_div #s-bns #s-sv-bn,.dark +.cc_div #s-bns #s-sv-bn:hover{color:var(--theme-color-secondary-200)}a.cc_div #s-bns #s-rall-bn,a +.cc_div #s-bns #s-sv-bn{display:inline-block}.dark .cc_div #s-bns #s-rall-bn:hover,.dark +.cc_div #s-bns #s-sv-bn:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.documentation-content a.cc_div #s-bns #s-rall-bn:hover,.documentation-content a +.cc_div #s-bns #s-sv-bn:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.documentation-content .page-ref .cc_div #s-bns #s-rall-bn,.documentation-content .page-ref +.cc_div #s-bns #s-sv-bn{border-radius:0}.dark .cc_div #s-bns #s-rall-bn:disabled,.dark +.cc_div #s-bns #s-sv-bn:disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.dark .dark .cc_div #s-bns #s-rall-bn:disabled,.dark .dark +.cc_div #s-bns #s-sv-bn:disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-700)}.dark .cc_div #s-bns #s-rall-bn,.dark +.cc_div #s-bns #s-sv-bn{border-radius:.25rem;font-weight:600;line-height:1.25;padding:.75rem 1.25rem;text-align:center;transition:all .1s ease-in}a.dark .cc_div #s-bns #s-rall-bn,a.dark +.cc_div #s-bns #s-sv-bn{display:inline-block}.dark .cc_div #s-bns #s-rall-bn,.dark +.cc_div #s-bns #s-sv-bn{--tw-text-opacity:1;background-color:var(--theme-color-secondary-800);color:rgb(255 255 255/var(--tw-text-opacity))}.dark .cc_div #s-bns #s-rall-bn:hover,.dark +.cc_div #s-bns #s-sv-bn:hover{background-color:var(--theme-color-secondary-900)}.dark .cc_div #s-bns #s-rall-bn a,.dark +.cc_div #s-bns #s-sv-bn a{display:inline-block}.dark .dark .cc_div #s-bns #s-rall-bn:hover,.dark .dark +.cc_div #s-bns #s-sv-bn:hover{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.cc_div #s-bns #s-rall-bn:hover,.cc_div #s-bns #s-sv-bn:hover,.dark .cc_div #s-bns #s-rall-bn:hover,.dark +.cc_div #s-bns #s-sv-bn:hover{--tw-text-opacity:1;background-color:var(--theme-color-primary-700);color:rgb(255 255 255/var(--tw-text-opacity));transition:all .1s ease-in}@media screen and (min-width:689px){.documentation-sidebar .cc_div #s-bns+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.cc_div #s-bns{display:flex;flex-direction:row-reverse;height:auto;padding-bottom:2.5rem}.cc_div #s-bns #s-rall-bn{margin-left:0;margin-right:1rem}.cc_div #s-bns #s-sv-bn{margin-right:auto}}.cc_div #s-bl .c-bl.b-ex{border:2px solid var(--theme-color-primary-100);border-radius:.75rem}.cc_div #s-bl .c-bl,.cc_div #s-bl .c-bl.b-ex{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.cc_div #s-bl .c-bl{border-width:0;padding:0}.cc_div .b-tg .c-tgl:checked:disabled~.c-tg,.cc_div .b-tg .c-tgl~.c-tg{background-color:var(--theme-color-secondary-400)}.cc_div .b-tg .c-tgl:checked~.c-tg{background-color:var(--theme-color-primary-600)}.cc_div #s-bl .b-acc .p,.cc_div #s-bl .c-bl .p{line-height:1.75rem}.cc_div .cloud #c-inr-i{width:80%}.cc_div button.c-bn{font-size:1rem;line-height:1.5rem;line-height:1.25;padding:.75rem 1.25rem}.cc_div div a{border-bottom-width:0}.cc_div #s-inr{border-radius:.75rem}.dark #s-bl .title,.dark #s-bl td:before,.dark #s-cnt .b-bn .b-tl,.dark .cc_div #c-ttl,.dark .cc_div #s-hdr #s-ttl{color:var(--theme-color-secondary-200)}.dark #c-txt,.dark #s-bl table{color:var(--theme-color-secondary-500)}.dark .cc_div #s-bl .c-bl{background-color:var(--theme-color-secondary-900);border-color:var(--theme-color-secondary-800)}.dark #s-bl table tr:hover,.dark #s-cnt .b-bn .b-tl:hover{background-color:var(--theme-color-secondary-800)}.dark #s-bl table tr{border-color:var(--theme-color-secondary-800)}.dark .cc_div .b-tg .c-tgl:checked:disabled~.c-tg,.dark .cc_div .b-tg .c-tgl~.c-tg{background-color:var(--theme-color-secondary-800)}.dark .cc_div .c-tgl:checked~.c-tg{background-color:var(--theme-color-primary-600)}.dark .cc_div .c-tgl:checked:not(:disabled)~.c-tg .on-i:before{--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}.dark .cc_div .c-tgl:checked:not(:disabled)~.c-tg:after,html{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}html{min-height:100%}.content{line-height:1.5}.table-header{font-size:1.5rem;font-weight:700;line-height:2rem}.paragraph-description{line-height:1.75rem}.modal-backdrop{background-color:rgba(0,0,0,.4);height:100vh;left:0;overflow:hidden;position:fixed;top:0;width:100vw;z-index:10}.bridgechain-items-grid{display:grid;gap:1rem 1rem;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));width:100%}@media (min-width:640px){.bridgechain-items-grid{display:grid;gap:1rem 1rem;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));width:100%}}.create-token--input-grid{display:grid;gap:1rem 1rem;grid-template-columns:repeat(auto-fill,minmax(20rem,1fr))}.contact-form--input-grid{display:grid;gap:1rem 1rem;grid-template-columns:repeat(auto-fill,minmax(18rem,1fr))}@media (min-width:768px){.contact-form--input-grid{grid-template-columns:repeat(auto-fill,minmax(25rem,1fr))}}.collaborator-grid{display:grid;gap:1rem 1rem;grid-template-columns:repeat(auto-fill,minmax(12rem,1fr))}@media (min-width:768px){.collaborator-grid{grid-template-columns:repeat(auto-fill,minmax(15rem,1fr))}}.fade-enter-active,.fade-leave-active{transition:opacity .5s}.fade-enter,.fade-leave-to{opacity:0}.terms-of-service ol{list-style-position:inside;list-style-type:decimal;margin-top:.75rem}.terms-of-service ol ol{margin-left:1rem}.terms-of-service ol li{margin-top:.25rem}.terms-of-service ol.roman{list-style-type:lower-roman}.terms-of-service--heading{font-size:1.125rem;font-weight:600;line-height:1.75rem;margin-top:1rem}.privacy-policy ul{list-style-position:inside;list-style-type:disc;margin-top:.75rem}.privacy-policy ul ul{margin-left:1rem}.privacy-policy ul li{margin-top:.25rem}div.disabled{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;background-color:var(--theme-color-secondary-200);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);color:var(--theme-color-secondary-400);cursor:not-allowed;pointer-events:none}.notification-truncate{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden;text-overflow:ellipsis}#swiper-tiers .swiper-slide{height:auto}.home-header-image{background:linear-gradient(0deg,#fff 50%,#f7fafb 0)}@media (min-width:768px){.home-header-image{background:linear-gradient(0deg,#fff 70%,#f7fafb 0)}}.documentation-sidebar body+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}body{color:var(--theme-color-secondary-700);display:flex;flex-direction:column;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;min-height:100vh}#app{flex-grow:1}.header-1{color:var(--theme-color-secondary-900);font-size:2.25rem;font-weight:700;line-height:2.5rem;line-height:1.25;margin-bottom:.5rem}.header-2{font-size:1.5rem;line-height:2rem}.header-2,.header-3{color:var(--theme-color-secondary-900);font-weight:700;margin-bottom:.25rem}.header-3{font-size:1.25rem;line-height:1.75rem}.header-4{color:var(--theme-color-secondary-900);font-size:1.125rem;font-weight:700;line-height:1.75rem;margin-bottom:.25rem}.welcome-screen{height:100%;max-height:200px;-o-object-fit:contain;object-fit:contain;width:100%}@media (min-width:768px){.welcome-screen{max-height:400px}}.beta-notice{height:100%;max-height:104px;-o-object-fit:contain;object-fit:contain;width:100%}#swiper-tokens,#swiper-tokens .swiper-wrapper{margin:0}#swiper-tokens .swiper-wrapper{padding-bottom:2rem}.table-container table tbody td:first-child{padding-left:0}.table-container table tbody td:last-child{padding-right:0}.documentation-sidebar button.dropdown-entry+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}button.dropdown-entry{--tw-bg-opacity:0;align-items:center;display:flex}a.alert-content>a.focus-visible,button.alert-content>a.focus-visible{border-radius:.25rem}a.alert-content>a:focus-visible,button.alert-content>a:focus-visible{border-radius:.25rem}.alert-content>a{color:var(--theme-color-primary-600);cursor:pointer;font-weight:600;-webkit-text-decoration-line:none;text-decoration-line:none;transition:all .1s ease-in}.simple-markdown a:is(.alert-content>a):hover{text-decoration:none}.alert-content>a.read-only{cursor:not-allowed}.alert-content>a:hover{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.alert-content>a.link-no-underline:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.simple-markdown a:is(.alert-content>a.link-no-underline:hover):hover{text-decoration:none}.alert-content>a:active{color:var(--theme-color-primary-400)}.description-block-link:hover .alert-content>a{color:var(--theme-color-primary-700);-webkit-text-decoration-line:underline;text-decoration-line:underline}.documentation-sidebar .dropdown-entry+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.dropdown-entry{align-items:center;display:flex}.dropdown-entry>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.dropdown-entry:hover{background-color:var(--theme-color-primary-100)}.documentation-sidebar .dropdown-entry span+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.dropdown-entry span{align-items:center;display:flex}.dropdown-entry span>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.dropdown-entry.delete-server,.dropdown-entry.delete-server:hover{color:var(--theme-color-danger-400)!important}.dropdown-entry.delete-server:hover{background-color:var(--theme-color-danger-100)!important}.dropdown-entry-disabled{background-color:var(--theme-color-secondary-100);color:var(--theme-color-secondary-500);cursor:pointer;display:block;font-weight:500;padding:1rem 2rem;text-align:left;transition-duration:.15s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);white-space:nowrap;width:100%}.table-container table>tbody>tr>td.hoverable-cell:is(.dropdown-entry-disabled)>div.table-cell-content{justify-content:flex-start}.dropdown-entry-disabled{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));color:var(--theme-color-secondary-900)}.dark .dropdown-entry-disabled{background-color:var(--theme-color-secondary-800);color:var(--theme-color-secondary-200)}.dropdown-entry-disabled:focus{outline:2px solid transparent;outline-offset:2px}.dropdown-entry-disabled:not([disabled]):not(.dropdown-entry-disabled):hover{background-color:var(--theme-color-secondary-100);color:var(--theme-color-secondary-900)}.dark .dropdown-entry-disabled:not([disabled]):not(.dropdown-entry-disabled):hover{background-color:var(--theme-color-secondary-900);color:var(--theme-color-secondary-200)}.dropdown-entry-disabled[disabled]{cursor:not-allowed;opacity:.5}.documentation-sidebar button.dropdown-entry-disabled+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}button.dropdown-entry-disabled{--tw-bg-opacity:0;align-items:center;display:flex}.documentation-sidebar .dropdown-entry-disabled+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.dropdown-entry-disabled{align-items:center;display:flex}.dropdown-entry-disabled>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.dropdown-entry-disabled:hover{background-color:var(--theme-color-primary-100)}.documentation-sidebar .dropdown-entry-disabled span+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.dropdown-entry-disabled span{align-items:center;display:flex}.dropdown-entry-disabled span>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.dropdown-entry-disabled.delete-server,.dropdown-entry-disabled.delete-server:hover{color:var(--theme-color-danger-400)!important}.dropdown-entry-disabled.delete-server:hover{background-color:var(--theme-color-danger-100)!important}.form-radio:checked.radio-checkmark{color:var(--theme-color-primary-500)!important}.form-checkbox:checked{color:var(--theme-color-primary-600)!important}.pagination{list-style:none}.documentation-sidebar .pagination+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.pagination{display:flex;justify-content:center;padding:0}.pagination .page-item .page-link{background-color:#fff;border-bottom-width:1px;border-left-width:1px;border-top-width:1px;color:#2779bd;display:block;padding:.75rem;text-decoration:none}.pagination .page-item .page-link:hover{background-color:#f1f5f8}.pagination .page-item:first-child .page-link{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.pagination .page-item:last-child .page-link{border-bottom-right-radius:.25rem;border-right-width:1px;border-top-right-radius:.25rem}.pagination .page-item.active .page-link{background-color:#2779bd;border-color:#2779bd;color:#fff}.pagination .page-item.disabled .page-link{background-color:#f1f5f8;color:#8795a1}.theme-deployer{--theme-color-primary-rgb:84,82,206;--theme-color-primary-50:#f5f5ff;--theme-color-primary-100:#e5e5ff;--theme-color-primary-200:#d6d5ff;--theme-color-primary-300:#9c9aff;--theme-color-primary-400:#6e6cef;--theme-color-primary-500:#5b59dc;--theme-color-primary-600:#5452ce;--theme-color-primary-700:#4745b0;--theme-color-primary-800:#363383;--theme-color-primary-900:#212052;--theme-color-secondary-50:#fcfdfd;--theme-color-secondary-100:#f7fafb;--theme-color-secondary-200:#eef3f5;--theme-color-secondary-300:#dbdee5;--theme-color-secondary-400:#c4c8cf;--theme-color-secondary-500:#a5adb9;--theme-color-secondary-600:#7e8a9c;--theme-color-secondary-700:#637282;--theme-color-secondary-800:#3c4249;--theme-color-secondary-900:#212225;--theme-color-danger-50:#fff5f2;--theme-color-danger-100:#ffe0da;--theme-color-danger-200:#feb8ae;--theme-color-danger-300:#ef7c6d;--theme-color-danger-400:#de5846;--theme-color-danger-500:#c9292c;--theme-color-danger-600:#b01e20;--theme-color-danger-700:#881a1b;--theme-color-danger-800:#5b1b1b;--theme-color-danger-900:#391919;--theme-color-warning-50:#fff8eb;--theme-color-warning-100:#ffe6b8;--theme-color-warning-200:#ffd486;--theme-color-warning-300:#ffc359;--theme-color-warning-400:#feb933;--theme-color-warning-500:#ffae10;--theme-color-warning-600:#fc9f0f;--theme-color-warning-700:#f88e0d;--theme-color-warning-800:#f27c0b;--theme-color-warning-900:#ec5c08;--theme-color-success-50:#f6fdf8;--theme-color-success-100:#edf7f0;--theme-color-success-200:#e2f0e6;--theme-color-success-300:#b0dbbc;--theme-color-success-400:#8cc69d;--theme-color-success-500:#42b263;--theme-color-success-600:#289548;--theme-color-success-700:#307845;--theme-color-success-800:#2b4f35;--theme-color-success-900:#26372b;--theme-color-info-50:#f5faff;--theme-color-info-100:#e5f0f8;--theme-color-info-200:#bad6f0;--theme-color-info-300:#99c7ee;--theme-color-info-400:#77b9f3;--theme-color-info-500:#3e9dff;--theme-color-info-600:#007dff;--theme-color-info-700:#075af2;--theme-color-info-800:#0b4dc7;--theme-color-info-900:#173e85}:root{--theme-color-primary-rgb:84,82,206;--theme-color-primary-50:#f5f5ff;--theme-color-primary-100:#e5e5ff;--theme-color-primary-200:#d6d5ff;--theme-color-primary-300:#9c9aff;--theme-color-primary-400:#6e6cef;--theme-color-primary-500:#5b59dc;--theme-color-primary-600:#5452ce;--theme-color-primary-700:#4745b0;--theme-color-primary-800:#363383;--theme-color-primary-900:#212052;--theme-color-secondary-50:#fcfdfd;--theme-color-secondary-100:#f7fafb;--theme-color-secondary-200:#eef3f5;--theme-color-secondary-300:#dbdee5;--theme-color-secondary-400:#c4c8cf;--theme-color-secondary-500:#a5adb9;--theme-color-secondary-600:#7e8a9c;--theme-color-secondary-700:#637282;--theme-color-secondary-800:#3c4249;--theme-color-secondary-900:#212225;--theme-color-danger-50:#fff5f2;--theme-color-danger-100:#ffe0da;--theme-color-danger-200:#feb8ae;--theme-color-danger-300:#ef7c6d;--theme-color-danger-400:#de5846;--theme-color-danger-500:#c9292c;--theme-color-danger-600:#b01e20;--theme-color-danger-700:#881a1b;--theme-color-danger-800:#5b1b1b;--theme-color-danger-900:#391919;--theme-color-warning-50:#fff8eb;--theme-color-warning-100:#ffe6b8;--theme-color-warning-200:#ffd486;--theme-color-warning-300:#ffc359;--theme-color-warning-400:#feb933;--theme-color-warning-500:#ffae10;--theme-color-warning-600:#fc9f0f;--theme-color-warning-700:#f88e0d;--theme-color-warning-800:#f27c0b;--theme-color-warning-900:#ec5c08;--theme-color-success-50:#f6fdf8;--theme-color-success-100:#edf7f0;--theme-color-success-200:#e2f0e6;--theme-color-success-300:#b0dbbc;--theme-color-success-400:#8cc69d;--theme-color-success-500:#42b263;--theme-color-success-600:#289548;--theme-color-success-700:#307845;--theme-color-success-800:#2b4f35;--theme-color-success-900:#26372b;--theme-color-info-50:#f5faff;--theme-color-info-100:#e5f0f8;--theme-color-info-200:#bad6f0;--theme-color-info-300:#99c7ee;--theme-color-info-400:#77b9f3;--theme-color-info-500:#3e9dff;--theme-color-info-600:#007dff;--theme-color-info-700:#075af2;--theme-color-info-800:#0b4dc7;--theme-color-info-900:#173e85}[x-cloak]{display:none!important}.last\:border-b-0:last-child{border-bottom-width:0}.last\:pb-4:last-child{padding-bottom:1rem}.focus-within\:border-theme-primary-500:focus-within{border-color:var(--theme-color-primary-500)}.hover\:border-theme-primary-600:hover{border-color:var(--theme-color-primary-600)}.hover\:border-theme-primary-700:hover{border-color:var(--theme-color-primary-700)}.hover\:border-transparent:hover{border-color:transparent}.hover\:border-theme-secondary-300:hover{border-color:var(--theme-color-secondary-300)}.hover\:border-theme-primary-200:hover{border-color:var(--theme-color-primary-200)}.hover\:border-theme-primary-400:hover{border-color:var(--theme-color-primary-400)}.hover\:bg-theme-primary-700:hover{background-color:var(--theme-color-primary-700)}.hover\:bg-theme-secondary-100:hover{background-color:var(--theme-color-secondary-100)}.hover\:bg-theme-secondary-300:hover{background-color:var(--theme-color-secondary-300)}.hover\:bg-theme-success-50:hover{background-color:var(--theme-color-success-50)}.hover\:bg-theme-danger-400:hover{background-color:var(--theme-color-danger-400)}.hover\:bg-theme-primary-100:hover{background-color:var(--theme-color-primary-100)}.hover\:bg-theme-primary-400:hover{background-color:var(--theme-color-primary-400)}.hover\:text-theme-primary-500:hover{color:var(--theme-color-primary-500)}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.hover\:text-theme-primary-400:hover{color:var(--theme-color-primary-400)}.hover\:text-theme-secondary-200:hover{color:var(--theme-color-secondary-200)}.hover\:text-theme-primary-600:hover{color:var(--theme-color-primary-600)}.hover\:text-theme-primary-700:hover{color:var(--theme-color-primary-700)}.hover\:text-theme-secondary-800:hover{color:var(--theme-color-secondary-800)}.hover\:underline:hover{-webkit-text-decoration-line:underline;text-decoration-line:underline}.hover\:no-underline:hover{-webkit-text-decoration-line:none;text-decoration-line:none}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-xl:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.hover\:shadow-lg:hover,.hover\:shadow-xl:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.hover\:outline-none:hover{outline:2px solid transparent;outline-offset:2px}.hover\:size-increase:hover{transform:scale(1.02)}.focus\:border-theme-danger-300:focus{border-color:var(--theme-color-danger-300)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-theme-danger-300:focus{--tw-ring-color:var(--theme-color-danger-300)}.focus-visible\:-mt-px.focus-visible{margin-top:-1px}.focus-visible\:-mt-px:focus-visible{margin-top:-1px}.focus-visible\:rounded.focus-visible{border-radius:.25rem}.focus-visible\:rounded:focus-visible{border-radius:.25rem}.focus-visible\:border-b-0.focus-visible{border-bottom-width:0}.focus-visible\:border-b-0:focus-visible{border-bottom-width:0}.focus-visible\:border-transparent.focus-visible{border-color:transparent}.focus-visible\:border-transparent:focus-visible{border-color:transparent}.focus-visible\:pt-0.focus-visible{padding-top:0}.focus-visible\:pt-0:focus-visible{padding-top:0}.focus-visible\:ring-2.focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-inset.focus-visible{--tw-ring-inset:inset}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset:inset}.focus-visible\:ring-theme-primary-500.focus-visible{--tw-ring-color:var(--theme-color-primary-500)}.focus-visible\:ring-theme-primary-500:focus-visible{--tw-ring-color:var(--theme-color-primary-500)}.group:hover .group-hover\:border-theme-primary-400{border-color:var(--theme-color-primary-400)}.group:hover .group-hover\:bg-transparent{background-color:transparent}.group:hover .group-hover\:bg-theme-primary-100{background-color:var(--theme-color-primary-100)}.group:hover .group-hover\:bg-theme-success-50{background-color:var(--theme-color-success-50)}.group:hover .group-hover\:text-theme-primary-600{color:var(--theme-color-primary-600)}.group:hover .group-hover\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.group:hover .group-hover\:text-theme-primary-700{color:var(--theme-color-primary-700)}.group:hover .group-hover\:text-theme-primary-500{color:var(--theme-color-primary-500)}.inverted .inverted\:border-theme-secondary-300{border-color:var(--theme-color-secondary-300)}.inverted .inverted\:border-transparent{border-color:transparent}.inverted .inverted\:border-theme-primary-600{border-color:var(--theme-color-primary-600)}.inverted .inverted\:bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.inverted .inverted\:text-theme-secondary-900{color:var(--theme-color-secondary-900)}.inverted .inverted\:text-theme-secondary-700{color:var(--theme-color-secondary-700)}.inverted .inverted\:shadow-header-smooth{--tw-shadow: 0px 2px 10px 0px rgba(192,200,207,.22);--tw-shadow-colored:0px 2px 10px 0px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.inverted .inverted\:hover\:border-theme-primary-600:hover{border-color:var(--theme-color-primary-600)}.inverted .inverted\:hover\:border-theme-secondary-300:hover{border-color:var(--theme-color-secondary-300)}.inverted .inverted\:hover\:bg-theme-primary-100:hover{background-color:var(--theme-color-primary-100)}.inverted .inverted\:hover\:text-theme-primary-700:hover{color:var(--theme-color-primary-700)}.inverted .inverted\:hover\:text-theme-secondary-900:hover{color:var(--theme-color-secondary-900)}.dark .dark\:block{display:block}.dark .dark\:hidden{display:none}.dark .dark\:border-theme-secondary-800,.dark .dark\:divide-theme-secondary-800>:not([hidden])~:not([hidden]){border-color:var(--theme-color-secondary-800)}.dark .dark\:border-theme-secondary-600{border-color:var(--theme-color-secondary-600)}.dark .dark\:border-theme-secondary-700{border-color:var(--theme-color-secondary-700)}.dark .dark\:bg-theme-secondary-800{background-color:var(--theme-color-secondary-800)}.dark .dark\:bg-black{--tw-bg-opacity:1;background-color:rgb(18 18 19/var(--tw-bg-opacity))}.dark .dark\:bg-theme-secondary-900{background-color:var(--theme-color-secondary-900)}.dark .dark\:bg-theme-danger-400{background-color:var(--theme-color-danger-400)}.dark .dark\:bg-theme-success-600{background-color:var(--theme-color-success-600)}.dark .dark\:bg-theme-warning-600{background-color:var(--theme-color-warning-600)}.dark .dark\:bg-theme-secondary-700{background-color:var(--theme-color-secondary-700)}.dark .dark\:bg-theme-success-900{background-color:var(--theme-color-success-900)}.dark .dark\:bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.dark .dark\:bg-opacity-95{--tw-bg-opacity:0.95}.dark .dark\:text-theme-secondary-200{color:var(--theme-color-secondary-200)}.dark .dark\:text-theme-secondary-700{color:var(--theme-color-secondary-700)}.dark .dark\:text-theme-secondary-500{color:var(--theme-color-secondary-500)}.dark .dark\:text-theme-secondary-600{color:var(--theme-color-secondary-600)}.dark .dark\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark .dark\:text-theme-secondary-300{color:var(--theme-color-secondary-300)}.dark .dark\:text-theme-secondary-400{color:var(--theme-color-secondary-400)}.dark .dark\:opacity-50{opacity:.5}.dark .dark\:shadow-lg-dark{--tw-shadow:0 0px 25px -3px rgba(18,18,19,.7),0 4px 15px 0px rgba(18,18,19,.7);--tw-shadow-colored:0 0px 25px -3px var(--tw-shadow-color),0 4px 15px 0px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dark .dark\:hover\:bg-theme-success-900:hover{background-color:var(--theme-color-success-900)}.dark .dark\:hover\:bg-theme-secondary-600:hover{background-color:var(--theme-color-secondary-600)}.dark .dark\:hover\:bg-theme-secondary-800:hover{background-color:var(--theme-color-secondary-800)}.dark .dark\:hover\:text-theme-secondary-800:hover{color:var(--theme-color-secondary-800)}.dark .dark\:hover\:text-theme-primary-600:hover{color:var(--theme-color-primary-600)}.dark .dark\:hover\:text-theme-secondary-400:hover{color:var(--theme-color-secondary-400)}.dark .dark\:hover\:text-theme-primary-700:hover{color:var(--theme-color-primary-700)}.dark .dark\:hover\:text-theme-secondary-100:hover{color:var(--theme-color-secondary-100)}.dark .group:hover .dark\:group-hover\:bg-theme-secondary-800{background-color:var(--theme-color-secondary-800)}.dark .group:hover .dark\:group-hover\:bg-theme-success-900{background-color:var(--theme-color-success-900)}.dark .group:hover .dark\:group-hover\:text-theme-secondary-100{color:var(--theme-color-secondary-100)}@media (min-width:640px){.sm\:static{position:static}.sm\:absolute{position:absolute}.sm\:relative{position:relative}.sm\:left-auto{left:auto}.sm\:top-0{top:0}.sm\:right-0{right:0}.sm\:bottom-0{bottom:0}.sm\:col-span-2{grid-column:span 2/span 2}.sm\:mx-0{margin-left:0;margin-right:0}.sm\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.sm\:mb-0{margin-bottom:0}.sm\:mt-5{margin-top:1.25rem}.sm\:mt-4{margin-top:1rem}.sm\:mt-0{margin-top:0}.sm\:mr-2{margin-right:.5rem}.sm\:mt-8{margin-top:2rem}.sm\:mr-8{margin-right:2rem}.sm\:-mt-1\.5{margin-top:-.375rem}.sm\:-mr-1\.5{margin-right:-.375rem}.sm\:-mt-1{margin-top:-.25rem}.sm\:-mr-1{margin-right:-.25rem}.sm\:mr-12{margin-right:3rem}.sm\:ml-6{margin-left:1.5rem}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:inline-flex{display:inline-flex}.sm\:table-cell{display:table-cell}.sm\:grid{display:grid}.sm\:hidden{display:none}.sm\:w-auto{width:auto}.sm\:w-1\/3{width:33.333333%}.sm\:w-80{width:20rem}.sm\:w-136{width:34rem}.sm\:max-w-xl{max-width:36rem}.sm\:max-w-none{max-width:none}.sm\:max-w-lg{max-width:32rem}.sm\:max-w-full{max-width:100%}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:flex-row-reverse{flex-direction:row-reverse}.sm\:flex-col{flex-direction:column}.sm\:items-start{align-items:flex-start}.sm\:items-center{align-items:center}.sm\:items-stretch{align-items:stretch}.sm\:justify-start{justify-content:flex-start}.sm\:justify-end{justify-content:flex-end}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:gap-4{gap:1rem}.sm\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.sm\:space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.sm\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.sm\:space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.sm\:space-x-5>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.25rem*var(--tw-space-x-reverse))}.sm\:space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.sm\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.sm\:space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.sm\:divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)));border-right-width:calc(1px*var(--tw-divide-x-reverse))}.sm\:divide-theme-secondary-200>:not([hidden])~:not([hidden]){border-color:var(--theme-color-secondary-200)}.sm\:rounded-xl{border-radius:.75rem}.sm\:rounded-lg{border-radius:.5rem}.sm\:border-2{border-width:2px}.sm\:border-r{border-right-width:1px}.sm\:border-t-0{border-top-width:0}.sm\:p-10{padding:2.5rem}.sm\:px-8{padding-left:2rem;padding-right:2rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:px-10{padding-left:2.5rem;padding-right:2.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:pr-6{padding-right:1.5rem}.sm\:pl-6{padding-left:1.5rem}.sm\:pt-8{padding-top:2rem}.sm\:pl-5{padding-left:1.25rem}.sm\:pl-8{padding-left:2rem}.sm\:pt-0{padding-top:0}.sm\:pl-4{padding-left:1rem}.sm\:text-center{text-align:center}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}.documentation-sidebar .sm\:flex+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}}@media (min-width:768px){.md\:absolute{position:absolute}.md\:relative{position:relative}.md\:col-span-2{grid-column:span 2/span 2}.md\:m-auto{margin:auto}.md\:mx-auto{margin-left:auto;margin-right:auto}.md\:mx-0{margin-left:0;margin-right:0}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:mb-0{margin-bottom:0}.md\:mt-0{margin-top:0}.md\:mb-4{margin-bottom:1rem}.md\:ml-4{margin-left:1rem}.md\:mt-3{margin-top:.75rem}.md\:mt-8{margin-top:2rem}.md\:mt-4{margin-top:1rem}.md\:ml-16{margin-left:4rem}.md\:mr-0{margin-right:0}.md\:mt-2{margin-top:.5rem}.md\:mr-12{margin-right:3rem}.md\:ml-12{margin-left:3rem}.md\:ml-6{margin-left:1.5rem}.md\:block{display:block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:table-cell{display:table-cell}.md\:hidden{display:none}.md\:h-11{height:2.75rem}.md\:h-4{height:1rem}.md\:h-3{height:.75rem}.md\:h-13{height:3.25rem}.md\:w-120{width:30rem}.md\:w-1\/5{width:20%}.md\:w-4\/5{width:80%}.md\:w-56{width:14rem}.md\:w-full{width:100%}.md\:w-11{width:2.75rem}.md\:w-auto{width:auto}.md\:w-4{width:1rem}.md\:w-2{width:.5rem}.md\:w-1\/4{width:25%}.md\:w-13{width:3.25rem}.md\:w-1\/2{width:50%}.md\:w-3\/4{width:75%}.md\:max-w-xl{max-width:36rem}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:flex-row-reverse{flex-direction:row-reverse}.md\:flex-col-reverse{flex-direction:column-reverse}.md\:items-end{align-items:flex-end}.md\:items-center{align-items:center}.md\:justify-end{justify-content:flex-end}.md\:justify-between{justify-content:space-between}.md\:space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.md\:space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.md\:space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.md\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.md\:space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.md\:rounded-xl{border-radius:.75rem}.md\:border-2{border-width:2px}.md\:border-0{border-width:0}.md\:border-b-0{border-bottom-width:0}.md\:border-r{border-right-width:1px}.md\:border-theme-primary-100{border-color:var(--theme-color-primary-100)}.md\:bg-theme-primary-100{background-color:var(--theme-color-primary-100)}.md\:bg-theme-primary-600{background-color:var(--theme-color-primary-600)}.md\:p-0{padding:0}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}.md\:py-4{padding-bottom:1rem;padding-top:1rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-10{padding-bottom:2.5rem;padding-top:2.5rem}.md\:px-5{padding-left:1.25rem;padding-right:1.25rem}.md\:px-0{padding-left:0;padding-right:0}.md\:py-12{padding-bottom:3rem;padding-top:3rem}.md\:py-2{padding-bottom:.5rem;padding-top:.5rem}.md\:py-8{padding-bottom:2rem;padding-top:2rem}.md\:pt-3{padding-top:.75rem}.md\:pb-0{padding-bottom:0}.md\:pr-8{padding-right:2rem}.md\:pl-10{padding-left:2.5rem}.md\:pr-16{padding-right:4rem}.md\:pt-8{padding-top:2rem}.md\:pt-12{padding-top:3rem}.md\:text-right{text-align:right}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-theme-secondary-700{color:var(--theme-color-secondary-700)}.md\:text-theme-primary-600{color:var(--theme-color-primary-600)}.md\:text-theme-secondary-100{color:var(--theme-color-secondary-100)}.documentation-sidebar .md\:flex+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}}@media (min-width:1024px){.lg\:my-1{margin-bottom:.25rem;margin-top:.25rem}.lg\:mx-0{margin-right:0}.lg\:ml-0,.lg\:mx-0{margin-left:0}.lg\:mt-0{margin-top:0}.lg\:ml-2{margin-left:.5rem}.lg\:mr-2{margin-right:.5rem}.lg\:mb-px{margin-bottom:1px}.lg\:ml-5{margin-left:1.25rem}.lg\:mr-0{margin-right:0}.lg\:ml-6{margin-left:1.5rem}.lg\:mt-8{margin-top:2rem}.lg\:block{display:block}.lg\:flex{display:flex}.lg\:table-cell{display:table-cell}.lg\:hidden{display:none}.lg\:h-12{height:3rem}.lg\:h-5{height:1.25rem}.lg\:h-11{height:2.75rem}.lg\:h-auto{height:auto}.lg\:w-3\/4{width:75%}.lg\:w-14{width:3.5rem}.lg\:w-5{width:1.25rem}.lg\:w-58{width:14.5rem}.lg\:w-1\/5{width:20%}.lg\:w-1\/2{width:50%}.lg\:w-auto{width:auto}.lg\:w-3\/5{width:60%}.lg\:min-w-0{min-width:0}.lg\:max-w-7xl{max-width:80rem}.lg\:max-w-none{max-width:none}.lg\:flex-1{flex:1 1 0%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:justify-start{justify-content:flex-start}.lg\:space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(0px*var(--tw-space-y-reverse));margin-top:calc(0px*(1 - var(--tw-space-y-reverse)))}.lg\:space-x-6>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1.5rem*var(--tw-space-x-reverse))}.lg\:space-x-12>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(3rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(3rem*var(--tw-space-x-reverse))}.lg\:divide-x>:not([hidden])~:not([hidden]){--tw-divide-x-reverse:0;border-left-width:calc(1px*(1 - var(--tw-divide-x-reverse)));border-right-width:calc(1px*var(--tw-divide-x-reverse))}.lg\:rounded-lg{border-radius:.5rem}.lg\:rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.lg\:border-r{border-right-width:1px}.lg\:px-10{padding-left:2.5rem;padding-right:2.5rem}.lg\:py-3{padding-bottom:.75rem;padding-top:.75rem}.lg\:px-0{padding-left:0;padding-right:0}.lg\:py-1{padding-bottom:.25rem;padding-top:.25rem}.lg\:pt-0{padding-top:0}.lg\:pr-5{padding-right:1.25rem}.lg\:pl-6{padding-left:1.5rem}.lg\:pt-4{padding-top:1rem}.lg\:pr-6{padding-right:1.5rem}.lg\:pl-10{padding-left:2.5rem}.lg\:pt-8{padding-top:2rem}.documentation-sidebar .lg\:flex+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}.lg\:no-wrap-span-children>span{white-space:nowrap}}@media (min-width:1280px){.xl\:mx-16{margin-left:4rem;margin-right:4rem}.xl\:mt-0{margin-top:0}.xl\:ml-6{margin-left:1.5rem}.xl\:block{display:block}.xl\:flex{display:flex}.xl\:table-cell{display:table-cell}.xl\:hidden{display:none}.xl\:w-1\/2{width:50%}.xl\:w-72{width:18rem}.xl\:w-36{width:9rem}.xl\:w-40{width:10rem}.xl\:w-48{width:12rem}.xl\:w-12{width:3rem}.xl\:w-1\/6{width:16.666667%}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(2rem*var(--tw-space-x-reverse))}.xl\:divide-y-0>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(0px*var(--tw-divide-y-reverse));border-top-width:calc(0px*(1 - var(--tw-divide-y-reverse)))}.xl\:px-0{padding-left:0;padding-right:0}.xl\:pb-3{padding-bottom:.75rem}.documentation-sidebar .xl\:flex+h2:not(.documentation-sidebar h2:first-of-type){margin-top:1rem}} diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..64cc8a5 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..fcaa720 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..332556d Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/fonts/FiraMono-Bold.otf b/public/fonts/FiraMono-Bold.otf new file mode 100644 index 0000000..540b042 Binary files /dev/null and b/public/fonts/FiraMono-Bold.otf differ diff --git a/public/fonts/FiraMono-Regular.otf b/public/fonts/FiraMono-Regular.otf new file mode 100644 index 0000000..d871626 Binary files /dev/null and b/public/fonts/FiraMono-Regular.otf differ diff --git a/public/fonts/FiraMono-RegularItalic.otf b/public/fonts/FiraMono-RegularItalic.otf new file mode 100644 index 0000000..2deafa6 Binary files /dev/null and b/public/fonts/FiraMono-RegularItalic.otf differ diff --git a/public/images/ark-logo.svg b/public/images/ark-logo.svg new file mode 100644 index 0000000..51ca5ca --- /dev/null +++ b/public/images/ark-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/auth/verify-email.svg b/public/images/auth/verify-email.svg new file mode 100644 index 0000000..9767dbc --- /dev/null +++ b/public/images/auth/verify-email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/bridgechain.svg b/public/images/bridgechain.svg new file mode 100644 index 0000000..9c8a97e --- /dev/null +++ b/public/images/bridgechain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/my-team.svg b/public/images/defaults/my-team.svg new file mode 100644 index 0000000..265dd57 --- /dev/null +++ b/public/images/defaults/my-team.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/no-notifications-navbar.svg b/public/images/defaults/no-notifications-navbar.svg new file mode 100644 index 0000000..8fab875 --- /dev/null +++ b/public/images/defaults/no-notifications-navbar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/no-notifications-page.svg b/public/images/defaults/no-notifications-page.svg new file mode 100644 index 0000000..98274fc --- /dev/null +++ b/public/images/defaults/no-notifications-page.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/no-notifications.svg b/public/images/defaults/no-notifications.svg new file mode 100644 index 0000000..8fab875 --- /dev/null +++ b/public/images/defaults/no-notifications.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/pending-invitation.svg b/public/images/defaults/pending-invitation.svg new file mode 100644 index 0000000..49e2558 --- /dev/null +++ b/public/images/defaults/pending-invitation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/defaults/user.svg b/public/images/defaults/user.svg new file mode 100644 index 0000000..0f8b92b --- /dev/null +++ b/public/images/defaults/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/home/basic.svg b/public/images/home/basic.svg new file mode 100644 index 0000000..301e7f1 --- /dev/null +++ b/public/images/home/basic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/home/customize.png b/public/images/home/customize.png new file mode 100644 index 0000000..b9e8d35 Binary files /dev/null and b/public/images/home/customize.png differ diff --git a/public/images/home/deploy.png b/public/images/home/deploy.png new file mode 100644 index 0000000..37ceb8d Binary files /dev/null and b/public/images/home/deploy.png differ diff --git a/public/images/home/enterprise.svg b/public/images/home/enterprise.svg new file mode 100644 index 0000000..5633ab7 --- /dev/null +++ b/public/images/home/enterprise.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/home/header.png b/public/images/home/header.png new file mode 100644 index 0000000..36fa7ad Binary files /dev/null and b/public/images/home/header.png differ diff --git a/public/images/home/manage.png b/public/images/home/manage.png new file mode 100644 index 0000000..3d4458f Binary files /dev/null and b/public/images/home/manage.png differ diff --git a/public/images/home/premium.svg b/public/images/home/premium.svg new file mode 100644 index 0000000..f2b7067 --- /dev/null +++ b/public/images/home/premium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/installation_complete.svg b/public/images/installation_complete.svg new file mode 100644 index 0000000..1a6d70d --- /dev/null +++ b/public/images/installation_complete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/installation_failed.svg b/public/images/installation_failed.svg new file mode 100644 index 0000000..4693abf --- /dev/null +++ b/public/images/installation_failed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/logo.svg b/public/images/logo.svg new file mode 100644 index 0000000..1f8038c --- /dev/null +++ b/public/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/mail/confirm.png b/public/images/mail/confirm.png new file mode 100644 index 0000000..2d13676 Binary files /dev/null and b/public/images/mail/confirm.png differ diff --git a/public/images/mail/github.png b/public/images/mail/github.png new file mode 100644 index 0000000..095d7ce Binary files /dev/null and b/public/images/mail/github.png differ diff --git a/public/images/mail/invitation.png b/public/images/mail/invitation.png new file mode 100644 index 0000000..badfa89 Binary files /dev/null and b/public/images/mail/invitation.png differ diff --git a/public/images/mail/logo.png b/public/images/mail/logo.png new file mode 100644 index 0000000..a4502d6 Binary files /dev/null and b/public/images/mail/logo.png differ diff --git a/public/images/mail/personal-data.png b/public/images/mail/personal-data.png new file mode 100644 index 0000000..17ba0cf Binary files /dev/null and b/public/images/mail/personal-data.png differ diff --git a/public/images/mail/reset-password.png b/public/images/mail/reset-password.png new file mode 100644 index 0000000..09168ea Binary files /dev/null and b/public/images/mail/reset-password.png differ diff --git a/public/images/mail/server.png b/public/images/mail/server.png new file mode 100644 index 0000000..9457408 Binary files /dev/null and b/public/images/mail/server.png differ diff --git a/public/images/mail/twitter.png b/public/images/mail/twitter.png new file mode 100644 index 0000000..c641abd Binary files /dev/null and b/public/images/mail/twitter.png differ diff --git a/public/images/mail/verify.png b/public/images/mail/verify.png new file mode 100644 index 0000000..bc4312c Binary files /dev/null and b/public/images/mail/verify.png differ diff --git a/public/images/metadata.png b/public/images/metadata.png new file mode 100644 index 0000000..460ac7e Binary files /dev/null and b/public/images/metadata.png differ diff --git a/public/images/modal/delete.svg b/public/images/modal/delete.svg new file mode 100644 index 0000000..9758009 --- /dev/null +++ b/public/images/modal/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/email-change-confirm.svg b/public/images/modal/email-change-confirm.svg new file mode 100644 index 0000000..5b64079 --- /dev/null +++ b/public/images/modal/email-change-confirm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/email-change.svg b/public/images/modal/email-change.svg new file mode 100644 index 0000000..aafb925 --- /dev/null +++ b/public/images/modal/email-change.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/expired-link.svg b/public/images/modal/expired-link.svg new file mode 100644 index 0000000..4715d62 --- /dev/null +++ b/public/images/modal/expired-link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/information.svg b/public/images/modal/information.svg new file mode 100644 index 0000000..93cd26b --- /dev/null +++ b/public/images/modal/information.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/invalid-link.svg b/public/images/modal/invalid-link.svg new file mode 100644 index 0000000..dc5aa28 --- /dev/null +++ b/public/images/modal/invalid-link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/success.svg b/public/images/modal/success.svg new file mode 100644 index 0000000..a688d04 --- /dev/null +++ b/public/images/modal/success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/modal/warning.svg b/public/images/modal/warning.svg new file mode 100644 index 0000000..7f93b0c --- /dev/null +++ b/public/images/modal/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/onboarding-footer.svg b/public/images/onboarding-footer.svg new file mode 100644 index 0000000..c56c650 --- /dev/null +++ b/public/images/onboarding-footer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/onboarding.svg b/public/images/onboarding.svg new file mode 100644 index 0000000..eddb5c6 --- /dev/null +++ b/public/images/onboarding.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/aws.svg b/public/images/server-providers/aws.svg new file mode 100644 index 0000000..cfb0ad7 --- /dev/null +++ b/public/images/server-providers/aws.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/digitalocean.svg b/public/images/server-providers/digitalocean.svg new file mode 100644 index 0000000..0a6d95e --- /dev/null +++ b/public/images/server-providers/digitalocean.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/hetnzer.svg b/public/images/server-providers/hetnzer.svg new file mode 100644 index 0000000..dbdb129 --- /dev/null +++ b/public/images/server-providers/hetnzer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/hetzner.svg b/public/images/server-providers/hetzner.svg new file mode 100644 index 0000000..dbdb129 --- /dev/null +++ b/public/images/server-providers/hetzner.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/linode.svg b/public/images/server-providers/linode.svg new file mode 100644 index 0000000..dbb9c14 --- /dev/null +++ b/public/images/server-providers/linode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server-providers/vultr.svg b/public/images/server-providers/vultr.svg new file mode 100644 index 0000000..f4037f7 --- /dev/null +++ b/public/images/server-providers/vultr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server/block-explorer.svg b/public/images/server/block-explorer.svg new file mode 100644 index 0000000..3c72fde --- /dev/null +++ b/public/images/server/block-explorer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/server/github.svg b/public/images/server/github.svg new file mode 100644 index 0000000..24d0ac0 --- /dev/null +++ b/public/images/server/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/status.svg b/public/images/status.svg new file mode 100644 index 0000000..8be3760 --- /dev/null +++ b/public/images/status.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/support.svg b/public/images/support.svg new file mode 100644 index 0000000..e864935 --- /dev/null +++ b/public/images/support.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/tokens.svg b/public/images/tokens.svg new file mode 100644 index 0000000..3f7d0fe --- /dev/null +++ b/public/images/tokens.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/vendor/ark/article/placeholder-banner.png b/public/images/vendor/ark/article/placeholder-banner.png new file mode 100644 index 0000000..d4d179f Binary files /dev/null and b/public/images/vendor/ark/article/placeholder-banner.png differ diff --git a/public/images/vendor/ark/search/empty-dark.svg b/public/images/vendor/ark/search/empty-dark.svg new file mode 100644 index 0000000..642f230 --- /dev/null +++ b/public/images/vendor/ark/search/empty-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/vendor/ark/search/empty.svg b/public/images/vendor/ark/search/empty.svg new file mode 100644 index 0000000..c4cad62 --- /dev/null +++ b/public/images/vendor/ark/search/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/verified-email.svg b/public/images/verified-email.svg new file mode 100644 index 0000000..9809c5f --- /dev/null +++ b/public/images/verified-email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/verify-email.svg b/public/images/verify-email.svg new file mode 100644 index 0000000..782c026 --- /dev/null +++ b/public/images/verify-email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/welcome/intro.svg b/public/images/welcome/intro.svg new file mode 100644 index 0000000..be90a50 --- /dev/null +++ b/public/images/welcome/intro.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/welcome/slide0.svg b/public/images/welcome/slide0.svg new file mode 100644 index 0000000..f8f610a --- /dev/null +++ b/public/images/welcome/slide0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/welcome/slide1.svg b/public/images/welcome/slide1.svg new file mode 100644 index 0000000..1f43c74 --- /dev/null +++ b/public/images/welcome/slide1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/welcome/slide2.svg b/public/images/welcome/slide2.svg new file mode 100644 index 0000000..3c1919a --- /dev/null +++ b/public/images/welcome/slide2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/welcome/slide3.svg b/public/images/welcome/slide3.svg new file mode 100644 index 0000000..8dab300 --- /dev/null +++ b/public/images/welcome/slide3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/wizard/bitbucket.svg b/public/images/wizard/bitbucket.svg new file mode 100644 index 0000000..872ee28 --- /dev/null +++ b/public/images/wizard/bitbucket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/wizard/github.svg b/public/images/wizard/github.svg new file mode 100644 index 0000000..bfbe951 --- /dev/null +++ b/public/images/wizard/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/wizard/gitlab.svg b/public/images/wizard/gitlab.svg new file mode 100644 index 0000000..5758971 --- /dev/null +++ b/public/images/wizard/gitlab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..2b5641b --- /dev/null +++ b/public/index.php @@ -0,0 +1,58 @@ + + */ +define('LARAVEL_START', microtime(true)); + +/* +|-------------------------------------------------------------------------- +| Register The Auto Loader +|-------------------------------------------------------------------------- +| +| Composer provides a convenient, automatically generated class loader for +| our application. We just need to utilize it! We'll simply require it +| into the script here so that we don't have to worry about manual +| loading any of our classes later on. It feels great to relax. +| +*/ + +require __DIR__.'/../vendor/autoload.php'; + +/* +|-------------------------------------------------------------------------- +| Turn On The Lights +|-------------------------------------------------------------------------- +| +| We need to illuminate PHP development, so let us turn on the lights. +| This bootstraps the framework and gets it ready for use, then it +| will load up this application so that we can run it and send +| the responses back to the browser and delight our users. +| +*/ + +$app = require_once __DIR__.'/../bootstrap/app.php'; + +/* +|-------------------------------------------------------------------------- +| Run The Application +|-------------------------------------------------------------------------- +| +| Once we have the application, we can handle the incoming request +| through the kernel, and send the associated response back to +| the client's browser allowing them to enjoy the creative +| and wonderful application we have prepared for them. +| +*/ + +$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); + +$response = $kernel->handle( + $request = Illuminate\Http\Request::capture() +); + +$response->send(); + +$kernel->terminate($request, $response); diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..2d26e79 --- /dev/null +++ b/public/js/app.js @@ -0,0 +1,2 @@ +/*! For license information please see app.js.LICENSE.txt */ +(self.webpackChunk=self.webpackChunk||[]).push([[773],{368:(e,t,n)=>{"use strict";var o=n(306);function r(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect();return{width:n.width/1,height:n.height/1,top:n.top/1,right:n.right/1,bottom:n.bottom/1,left:n.left/1,x:n.left/1,y:n.top/1}}function i(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function a(e){var t=i(e);return{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function s(e){return e instanceof i(e).Element||e instanceof Element}function c(e){return e instanceof i(e).HTMLElement||e instanceof HTMLElement}function u(e){return"undefined"!=typeof ShadowRoot&&(e instanceof i(e).ShadowRoot||e instanceof ShadowRoot)}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((s(e)?e.ownerDocument:e.document)||window.document).documentElement}function p(e){return r(d(e)).left+a(e).scrollLeft}function f(e){return i(e).getComputedStyle(e)}function h(e){var t=f(e),n=t.overflow,o=t.overflowX,r=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+r+o)}function v(e,t,n){void 0===n&&(n=!1);var o,s,u=c(t),f=c(t)&&function(e){var t=e.getBoundingClientRect(),n=t.width/e.offsetWidth||1,o=t.height/e.offsetHeight||1;return 1!==n||1!==o}(t),v=d(t),m=r(e,f),b={scrollLeft:0,scrollTop:0},g={x:0,y:0};return(u||!u&&!n)&&(("body"!==l(t)||h(v))&&(b=(o=t)!==i(o)&&c(o)?{scrollLeft:(s=o).scrollLeft,scrollTop:s.scrollTop}:a(o)),c(t)?((g=r(t,!0)).x+=t.clientLeft,g.y+=t.clientTop):v&&(g.x=p(v))),{x:m.left+b.scrollLeft-g.x,y:m.top+b.scrollTop-g.y,width:m.width,height:m.height}}function m(e){var t=r(e),n=e.offsetWidth,o=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-o)<=1&&(o=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:o}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(u(e)?e.host:null)||d(e)}function g(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:c(e)&&h(e)?e:g(b(e))}function y(e,t){var n;void 0===t&&(t=[]);var o=g(e),r=o===(null==(n=e.ownerDocument)?void 0:n.body),a=i(o),s=r?[a].concat(a.visualViewport||[],h(o)?o:[]):o,c=t.concat(s);return r?c:c.concat(y(b(s)))}function w(e){return["table","td","th"].indexOf(l(e))>=0}function O(e){return c(e)&&"fixed"!==f(e).position?e.offsetParent:null}function x(e){for(var t=i(e),n=O(e);n&&w(n)&&"static"===f(n).position;)n=O(n);return n&&("html"===l(n)||"body"===l(n)&&"static"===f(n).position)?t:n||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&c(e)&&"fixed"===f(e).position)return null;for(var n=b(e);c(n)&&["html","body"].indexOf(l(n))<0;){var o=f(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||t}var E="top",k="bottom",j="right",S="left",A="auto",T=[E,k,j,S],D="start",P="end",C="viewport",L="popper",M=T.reduce((function(e,t){return e.concat([t+"-"+D,t+"-"+P])}),[]),N=[].concat(T,[A]).reduce((function(e,t){return e.concat([t,t+"-"+D,t+"-"+P])}),[]),B=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function R(e){var t=new Map,n=new Set,o=[];function r(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var o=t.get(e);o&&r(o)}})),o.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||r(e)})),o}var I={placement:"bottom",modifiers:[],strategy:"absolute"};function _(){for(var e=arguments.length,t=new Array(e),n=0;n=0?"x":"y"}function $(e){var t,n=e.reference,o=e.element,r=e.placement,i=r?q(r):null,a=r?V(r):null,s=n.x+n.width/2-o.width/2,c=n.y+n.height/2-o.height/2;switch(i){case E:t={x:s,y:n.y-o.height};break;case k:t={x:s,y:n.y+n.height};break;case j:t={x:n.x+n.width,y:c};break;case S:t={x:n.x-o.width,y:c};break;default:t={x:n.x,y:n.y}}var u=i?G(i):null;if(null!=u){var l="y"===u?"height":"width";switch(a){case D:t[u]=t[u]-(n[l]/2-o[l]/2);break;case P:t[u]=t[u]+(n[l]/2-o[l]/2)}}return t}const U={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=$({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}};var z=Math.max,Y=Math.min,K=Math.round,X={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Z(e){var t,n=e.popper,o=e.popperRect,r=e.placement,a=e.variation,s=e.offsets,c=e.position,u=e.gpuAcceleration,l=e.adaptive,p=e.roundOffsets,h=!0===p?function(e){var t=e.x,n=e.y,o=window.devicePixelRatio||1;return{x:K(K(t*o)/o)||0,y:K(K(n*o)/o)||0}}(s):"function"==typeof p?p(s):s,v=h.x,m=void 0===v?0:v,b=h.y,g=void 0===b?0:b,y=s.hasOwnProperty("x"),w=s.hasOwnProperty("y"),O=S,A=E,T=window;if(l){var D=x(n),C="clientHeight",L="clientWidth";D===i(n)&&"static"!==f(D=d(n)).position&&"absolute"===c&&(C="scrollHeight",L="scrollWidth"),D=D,r!==E&&(r!==S&&r!==j||a!==P)||(A=k,g-=D[C]-o.height,g*=u?1:-1),r!==S&&(r!==E&&r!==k||a!==P)||(O=j,m-=D[L]-o.width,m*=u?1:-1)}var M,N=Object.assign({position:c},l&&X);return u?Object.assign({},N,((M={})[A]=w?"0":"",M[O]=y?"0":"",M.transform=(T.devicePixelRatio||1)<=1?"translate("+m+"px, "+g+"px)":"translate3d("+m+"px, "+g+"px, 0)",M)):Object.assign({},N,((t={})[A]=w?g+"px":"",t[O]=y?m+"px":"",t.transform="",t))}const J={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,o=n.gpuAcceleration,r=void 0===o||o,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,c=void 0===s||s,u={placement:q(t.placement),variation:V(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,Z(Object.assign({},u,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:c})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,Z(Object.assign({},u,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:c})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};const Q={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];c(r)&&l(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});c(o)&&l(o)&&(Object.assign(o.style,i),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};const ee={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.offset,i=void 0===r?[0,0]:r,a=N.reduce((function(e,n){return e[n]=function(e,t,n){var o=q(e),r=[S,E].indexOf(o)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*r,[S,j].indexOf(o)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],c=s.x,u=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=c,t.modifiersData.popperOffsets.y+=u),t.modifiersData[o]=a}};var te={left:"right",right:"left",bottom:"top",top:"bottom"};function ne(e){return e.replace(/left|right|bottom|top/g,(function(e){return te[e]}))}var oe={start:"end",end:"start"};function re(e){return e.replace(/start|end/g,(function(e){return oe[e]}))}function ie(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&u(n)){var o=t;do{if(o&&e.isSameNode(o))return!0;o=o.parentNode||o.host}while(o)}return!1}function ae(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function se(e,t){return t===C?ae(function(e){var t=i(e),n=d(e),o=t.visualViewport,r=n.clientWidth,a=n.clientHeight,s=0,c=0;return o&&(r=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,c=o.offsetTop)),{width:r,height:a,x:s+p(e),y:c}}(e)):c(t)?function(e){var t=r(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(t):ae(function(e){var t,n=d(e),o=a(e),r=null==(t=e.ownerDocument)?void 0:t.body,i=z(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),s=z(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),c=-o.scrollLeft+p(e),u=-o.scrollTop;return"rtl"===f(r||n).direction&&(c+=z(n.clientWidth,r?r.clientWidth:0)-i),{width:i,height:s,x:c,y:u}}(d(e)))}function ce(e,t,n){var o="clippingParents"===t?function(e){var t=y(b(e)),n=["absolute","fixed"].indexOf(f(e).position)>=0&&c(e)?x(e):e;return s(n)?t.filter((function(e){return s(e)&&ie(e,n)&&"body"!==l(e)})):[]}(e):[].concat(t),r=[].concat(o,[n]),i=r[0],a=r.reduce((function(t,n){var o=se(e,n);return t.top=z(o.top,t.top),t.right=Y(o.right,t.right),t.bottom=Y(o.bottom,t.bottom),t.left=z(o.left,t.left),t}),se(e,i));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}function ue(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function le(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function de(e,t){void 0===t&&(t={});var n=t,o=n.placement,i=void 0===o?e.placement:o,a=n.boundary,c=void 0===a?"clippingParents":a,u=n.rootBoundary,l=void 0===u?C:u,p=n.elementContext,f=void 0===p?L:p,h=n.altBoundary,v=void 0!==h&&h,m=n.padding,b=void 0===m?0:m,g=ue("number"!=typeof b?b:le(b,T)),y=f===L?"reference":L,w=e.rects.popper,O=e.elements[v?y:f],x=ce(s(O)?O:O.contextElement||d(e.elements.popper),c,l),S=r(e.elements.reference),A=$({reference:S,element:w,strategy:"absolute",placement:i}),D=ae(Object.assign({},w,A)),P=f===L?D:S,M={top:x.top-P.top+g.top,bottom:P.bottom-x.bottom+g.bottom,left:x.left-P.left+g.left,right:P.right-x.right+g.right},N=e.modifiersData.offset;if(f===L&&N){var B=N[i];Object.keys(M).forEach((function(e){var t=[j,k].indexOf(e)>=0?1:-1,n=[E,k].indexOf(e)>=0?"y":"x";M[e]+=B[n]*t}))}return M}const pe={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name;if(!t.modifiersData[o]._skip){for(var r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0===a||a,c=n.fallbackPlacements,u=n.padding,l=n.boundary,d=n.rootBoundary,p=n.altBoundary,f=n.flipVariations,h=void 0===f||f,v=n.allowedAutoPlacements,m=t.options.placement,b=q(m),g=c||(b===m||!h?[ne(m)]:function(e){if(q(e)===A)return[];var t=ne(e);return[re(e),t,re(t)]}(m)),y=[m].concat(g).reduce((function(e,n){return e.concat(q(n)===A?function(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,c=n.allowedAutoPlacements,u=void 0===c?N:c,l=V(o),d=l?s?M:M.filter((function(e){return V(e)===l})):T,p=d.filter((function(e){return u.indexOf(e)>=0}));0===p.length&&(p=d);var f=p.reduce((function(t,n){return t[n]=de(e,{placement:n,boundary:r,rootBoundary:i,padding:a})[q(n)],t}),{});return Object.keys(f).sort((function(e,t){return f[e]-f[t]}))}(t,{placement:n,boundary:l,rootBoundary:d,padding:u,flipVariations:h,allowedAutoPlacements:v}):n)}),[]),w=t.rects.reference,O=t.rects.popper,x=new Map,P=!0,C=y[0],L=0;L=0,F=_?"width":"height",H=de(t,{placement:B,boundary:l,rootBoundary:d,altBoundary:p,padding:u}),W=_?I?j:S:I?k:E;w[F]>O[F]&&(W=ne(W));var G=ne(W),$=[];if(i&&$.push(H[R]<=0),s&&$.push(H[W]<=0,H[G]<=0),$.every((function(e){return e}))){C=B,P=!1;break}x.set(B,$)}if(P)for(var U=function(e){var t=y.find((function(t){var n=x.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return C=t,"break"},z=h?3:1;z>0;z--){if("break"===U(z))break}t.placement!==C&&(t.modifiersData[o]._skip=!0,t.placement=C,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function fe(e,t,n){return z(e,Y(t,n))}const he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0!==a&&a,c=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,p=n.tether,f=void 0===p||p,h=n.tetherOffset,v=void 0===h?0:h,b=de(t,{boundary:c,rootBoundary:u,padding:d,altBoundary:l}),g=q(t.placement),y=V(t.placement),w=!y,O=G(g),A="x"===O?"y":"x",T=t.modifiersData.popperOffsets,P=t.rects.reference,C=t.rects.popper,L="function"==typeof v?v(Object.assign({},t.rects,{placement:t.placement})):v,M={x:0,y:0};if(T){if(i||s){var N="y"===O?E:S,B="y"===O?k:j,R="y"===O?"height":"width",I=T[O],_=T[O]+b[N],F=T[O]-b[B],H=f?-C[R]/2:0,W=y===D?P[R]:C[R],$=y===D?-C[R]:-P[R],U=t.elements.arrow,K=f&&U?m(U):{width:0,height:0},X=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},Z=X[N],J=X[B],Q=fe(0,P[R],K[R]),ee=w?P[R]/2-H-Q-Z-L:W-Q-Z-L,te=w?-P[R]/2+H+Q+J+L:$+Q+J+L,ne=t.elements.arrow&&x(t.elements.arrow),oe=ne?"y"===O?ne.clientTop||0:ne.clientLeft||0:0,re=t.modifiersData.offset?t.modifiersData.offset[t.placement][O]:0,ie=T[O]+ee-re-oe,ae=T[O]+te-re;if(i){var se=fe(f?Y(_,ie):_,I,f?z(F,ae):F);T[O]=se,M[O]=se-I}if(s){var ce="x"===O?E:S,ue="x"===O?k:j,le=T[A],pe=le+b[ce],he=le-b[ue],ve=fe(f?Y(pe,ie):pe,le,f?z(he,ae):he);T[A]=ve,M[A]=ve-le}}t.modifiersData[o]=M}},requiresIfExists:["offset"]};const ve={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,o=e.name,r=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=q(n.placement),c=G(s),u=[S,j].indexOf(s)>=0?"height":"width";if(i&&a){var l=function(e,t){return ue("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:le(e,T))}(r.padding,n),d=m(i),p="y"===c?E:S,f="y"===c?k:j,h=n.rects.reference[u]+n.rects.reference[c]-a[c]-n.rects.popper[u],v=a[c]-n.rects.reference[c],b=x(i),g=b?"y"===c?b.clientHeight||0:b.clientWidth||0:0,y=h/2-v/2,w=l[p],O=g-d[u]-l[f],A=g/2-d[u]/2+y,D=fe(w,A,O),P=c;n.modifiersData[o]=((t={})[P]=D,t.centerOffset=D-A,t)}},effect:function(e){var t=e.state,n=e.options.element,o=void 0===n?"[data-popper-arrow]":n;null!=o&&("string"!=typeof o||(o=t.elements.popper.querySelector(o)))&&ie(t.elements.popper,o)&&(t.elements.arrow=o)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function me(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function be(e){return[E,j,k,S].some((function(t){return e[t]>=0}))}var ge=F({defaultModifiers:[W,U,J,Q,ee,pe,he,ve,{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,o=t.rects.reference,r=t.rects.popper,i=t.modifiersData.preventOverflow,a=de(t,{elementContext:"reference"}),s=de(t,{altBoundary:!0}),c=me(a,o),u=me(s,r,i),l=be(c),d=be(u);t.modifiersData[n]={referenceClippingOffsets:c,popperEscapeOffsets:u,isReferenceHidden:l,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":l,"data-popper-escaped":d})}}]}),ye="tippy-content",we="tippy-backdrop",Oe="tippy-arrow",xe="tippy-svg-arrow",Ee={passive:!0,capture:!0},ke=function(){return document.body};function je(e,t,n){if(Array.isArray(e)){var o=e[t];return null==o?Array.isArray(n)?n[t]:n:o}return e}function Se(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function Ae(e,t){return"function"==typeof e?e.apply(void 0,t):e}function Te(e,t){return 0===t?e:function(o){clearTimeout(n),n=setTimeout((function(){e(o)}),t)};var n}function De(e){return[].concat(e)}function Pe(e,t){-1===e.indexOf(t)&&e.push(t)}function Ce(e){return e.split("-")[0]}function Le(e){return[].slice.call(e)}function Me(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function Ne(){return document.createElement("div")}function Be(e){return["Element","Fragment"].some((function(t){return Se(e,t)}))}function Re(e){return Se(e,"MouseEvent")}function Ie(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function _e(e){return Be(e)?[e]:function(e){return Se(e,"NodeList")}(e)?Le(e):Array.isArray(e)?e:Le(document.querySelectorAll(e))}function Fe(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function He(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function We(e){var t,n=De(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function qe(e,t,n){var o=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[o](t,n)}))}function Ve(e,t){for(var n=t;n;){var o;if(e.contains(n))return!0;n=null==n.getRootNode||null==(o=n.getRootNode())?void 0:o.host}return!1}var Ge={isTouch:!1},$e=0;function Ue(){Ge.isTouch||(Ge.isTouch=!0,window.performance&&document.addEventListener("mousemove",ze))}function ze(){var e=performance.now();e-$e<20&&(Ge.isTouch=!1,document.removeEventListener("mousemove",ze)),$e=e}function Ye(){var e=document.activeElement;if(Ie(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var Ke=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto;var Xe={animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},Ze=Object.assign({appendTo:ke,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},Xe,{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),Je=Object.keys(Ze);function Qe(e){var t=(e.plugins||[]).reduce((function(t,n){var o,r=n.name,i=n.defaultValue;r&&(t[r]=void 0!==e[r]?e[r]:null!=(o=Ze[r])?o:i);return t}),{});return Object.assign({},e,t)}function et(e,t){var n=Object.assign({},t,{content:Ae(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(Qe(Object.assign({},Ze,{plugins:t}))):Je).reduce((function(t,n){var o=(e.getAttribute("data-tippy-"+n)||"").trim();if(!o)return t;if("content"===n)t[n]=o;else try{t[n]=JSON.parse(o)}catch(e){t[n]=o}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},Ze.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function tt(e,t){e.innerHTML=t}function nt(e){var t=Ne();return!0===e?t.className=Oe:(t.className=xe,Be(e)?t.appendChild(e):tt(t,e)),t}function ot(e,t){Be(t.content)?(tt(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?tt(e,t.content):e.textContent=t.content)}function rt(e){var t=e.firstElementChild,n=Le(t.children);return{box:t,content:n.find((function(e){return e.classList.contains(ye)})),arrow:n.find((function(e){return e.classList.contains(Oe)||e.classList.contains(xe)})),backdrop:n.find((function(e){return e.classList.contains(we)}))}}function it(e){var t=Ne(),n=Ne();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var o=Ne();function r(n,o){var r=rt(t),i=r.box,a=r.content,s=r.arrow;o.theme?i.setAttribute("data-theme",o.theme):i.removeAttribute("data-theme"),"string"==typeof o.animation?i.setAttribute("data-animation",o.animation):i.removeAttribute("data-animation"),o.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof o.maxWidth?o.maxWidth+"px":o.maxWidth,o.role?i.setAttribute("role",o.role):i.removeAttribute("role"),n.content===o.content&&n.allowHTML===o.allowHTML||ot(a,e.props),o.arrow?s?n.arrow!==o.arrow&&(i.removeChild(s),i.appendChild(nt(o.arrow))):i.appendChild(nt(o.arrow)):s&&i.removeChild(s)}return o.className=ye,o.setAttribute("data-state","hidden"),ot(o,e.props),t.appendChild(n),n.appendChild(o),r(e.props,e.props),{popper:t,onUpdate:r}}it.$$tippy=!0;var at=1,st=[],ct=[];function ut(e,t){var n,o,r,i,a,s,c,u,l=et(e,Object.assign({},Ze,Qe(Me(t)))),d=!1,p=!1,f=!1,h=!1,v=[],m=Te(z,l.interactiveDebounce),b=at++,g=(u=l.plugins).filter((function(e,t){return u.indexOf(e)===t})),y={id:b,reference:e,popper:Ne(),popperInstance:null,props:l,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:g,clearDelayTimeouts:function(){clearTimeout(n),clearTimeout(o),cancelAnimationFrame(r)},setProps:function(t){0;if(y.state.isDestroyed)return;M("onBeforeUpdate",[y,t]),$();var n=y.props,o=et(e,Object.assign({},n,Me(t),{ignoreAttributes:!0}));y.props=o,G(),n.interactiveDebounce!==o.interactiveDebounce&&(R(),m=Te(z,o.interactiveDebounce));n.triggerTarget&&!o.triggerTarget?De(n.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):o.triggerTarget&&e.removeAttribute("aria-expanded");B(),L(),x&&x(n,o);y.popperInstance&&(Z(),Q().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));M("onAfterUpdate",[y,t])},setContent:function(e){y.setProps({content:e})},show:function(){0;var e=y.state.isVisible,t=y.state.isDestroyed,n=!y.state.isEnabled,o=Ge.isTouch&&!y.props.touch,r=je(y.props.duration,0,Ze.duration);if(e||t||n||o)return;if(T().hasAttribute("disabled"))return;if(M("onShow",[y],!1),!1===y.props.onShow(y))return;y.state.isVisible=!0,A()&&(O.style.visibility="visible");L(),H(),y.state.isMounted||(O.style.transition="none");if(A()){var i=P(),a=i.box,c=i.content;Fe([a,c],0)}s=function(){var e;if(y.state.isVisible&&!h){if(h=!0,O.offsetHeight,O.style.transition=y.props.moveTransition,A()&&y.props.animation){var t=P(),n=t.box,o=t.content;Fe([n,o],r),He([n,o],"visible")}N(),B(),Pe(ct,y),null==(e=y.popperInstance)||e.forceUpdate(),M("onMount",[y]),y.props.animation&&A()&&function(e,t){q(e,t)}(r,(function(){y.state.isShown=!0,M("onShown",[y])}))}},function(){var e,t=y.props.appendTo,n=T();e=y.props.interactive&&t===ke||"parent"===t?n.parentNode:Ae(t,[n]);e.contains(O)||e.appendChild(O);y.state.isMounted=!0,Z(),!1}()},hide:function(){0;var e=!y.state.isVisible,t=y.state.isDestroyed,n=!y.state.isEnabled,o=je(y.props.duration,1,Ze.duration);if(e||t||n)return;if(M("onHide",[y],!1),!1===y.props.onHide(y))return;y.state.isVisible=!1,y.state.isShown=!1,h=!1,d=!1,A()&&(O.style.visibility="hidden");if(R(),W(),L(!0),A()){var r=P(),i=r.box,a=r.content;y.props.animation&&(Fe([i,a],o),He([i,a],"hidden"))}N(),B(),y.props.animation?A()&&function(e,t){q(e,(function(){!y.state.isVisible&&O.parentNode&&O.parentNode.contains(O)&&t()}))}(o,y.unmount):y.unmount()},hideWithInteractivity:function(e){0;D().addEventListener("mousemove",m),Pe(st,m),m(e)},enable:function(){y.state.isEnabled=!0},disable:function(){y.hide(),y.state.isEnabled=!1},unmount:function(){0;y.state.isVisible&&y.hide();if(!y.state.isMounted)return;J(),Q().forEach((function(e){e._tippy.unmount()})),O.parentNode&&O.parentNode.removeChild(O);ct=ct.filter((function(e){return e!==y})),y.state.isMounted=!1,M("onHidden",[y])},destroy:function(){0;if(y.state.isDestroyed)return;y.clearDelayTimeouts(),y.unmount(),$(),delete e._tippy,y.state.isDestroyed=!0,M("onDestroy",[y])}};if(!l.render)return y;var w=l.render(y),O=w.popper,x=w.onUpdate;O.setAttribute("data-tippy-root",""),O.id="tippy-"+y.id,y.popper=O,e._tippy=y,O._tippy=y;var E=g.map((function(e){return e.fn(y)})),k=e.hasAttribute("aria-expanded");return G(),B(),L(),M("onCreate",[y]),l.showOnCreate&&ee(),O.addEventListener("mouseenter",(function(){y.props.interactive&&y.state.isVisible&&y.clearDelayTimeouts()})),O.addEventListener("mouseleave",(function(){y.props.interactive&&y.props.trigger.indexOf("mouseenter")>=0&&D().addEventListener("mousemove",m)})),y;function j(){var e=y.props.touch;return Array.isArray(e)?e:[e,0]}function S(){return"hold"===j()[0]}function A(){var e;return!(null==(e=y.props.render)||!e.$$tippy)}function T(){return c||e}function D(){var e=T().parentNode;return e?We(e):document}function P(){return rt(O)}function C(e){return y.state.isMounted&&!y.state.isVisible||Ge.isTouch||i&&"focus"===i.type?0:je(y.props.delay,e?0:1,Ze.delay)}function L(e){void 0===e&&(e=!1),O.style.pointerEvents=y.props.interactive&&!e?"":"none",O.style.zIndex=""+y.props.zIndex}function M(e,t,n){var o;(void 0===n&&(n=!0),E.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(o=y.props)[e].apply(o,t)}function N(){var t=y.props.aria;if(t.content){var n="aria-"+t.content,o=O.id;De(y.props.triggerTarget||e).forEach((function(e){var t=e.getAttribute(n);if(y.state.isVisible)e.setAttribute(n,t?t+" "+o:o);else{var r=t&&t.replace(o,"").trim();r?e.setAttribute(n,r):e.removeAttribute(n)}}))}}function B(){!k&&y.props.aria.expanded&&De(y.props.triggerTarget||e).forEach((function(e){y.props.interactive?e.setAttribute("aria-expanded",y.state.isVisible&&e===T()?"true":"false"):e.removeAttribute("aria-expanded")}))}function R(){D().removeEventListener("mousemove",m),st=st.filter((function(e){return e!==m}))}function I(t){if(!Ge.isTouch||!f&&"mousedown"!==t.type){var n=t.composedPath&&t.composedPath()[0]||t.target;if(!y.props.interactive||!Ve(O,n)){if(De(y.props.triggerTarget||e).some((function(e){return Ve(e,n)}))){if(Ge.isTouch)return;if(y.state.isVisible&&y.props.trigger.indexOf("click")>=0)return}else M("onClickOutside",[y,t]);!0===y.props.hideOnClick&&(y.clearDelayTimeouts(),y.hide(),p=!0,setTimeout((function(){p=!1})),y.state.isMounted||W())}}}function _(){f=!0}function F(){f=!1}function H(){var e=D();e.addEventListener("mousedown",I,!0),e.addEventListener("touchend",I,Ee),e.addEventListener("touchstart",F,Ee),e.addEventListener("touchmove",_,Ee)}function W(){var e=D();e.removeEventListener("mousedown",I,!0),e.removeEventListener("touchend",I,Ee),e.removeEventListener("touchstart",F,Ee),e.removeEventListener("touchmove",_,Ee)}function q(e,t){var n=P().box;function o(e){e.target===n&&(qe(n,"remove",o),t())}if(0===e)return t();qe(n,"remove",a),qe(n,"add",o),a=o}function V(t,n,o){void 0===o&&(o=!1),De(y.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,o),v.push({node:e,eventType:t,handler:n,options:o})}))}function G(){var e;S()&&(V("touchstart",U,{passive:!0}),V("touchend",Y,{passive:!0})),(e=y.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(V(e,U),e){case"mouseenter":V("mouseleave",Y);break;case"focus":V(Ke?"focusout":"blur",K);break;case"focusin":V("focusout",K)}}))}function $(){v.forEach((function(e){var t=e.node,n=e.eventType,o=e.handler,r=e.options;t.removeEventListener(n,o,r)})),v=[]}function U(e){var t,n=!1;if(y.state.isEnabled&&!X(e)&&!p){var o="focus"===(null==(t=i)?void 0:t.type);i=e,c=e.currentTarget,B(),!y.state.isVisible&&Re(e)&&st.forEach((function(t){return t(e)})),"click"===e.type&&(y.props.trigger.indexOf("mouseenter")<0||d)&&!1!==y.props.hideOnClick&&y.state.isVisible?n=!0:ee(e),"click"===e.type&&(d=!n),n&&!o&&te(e)}}function z(e){var t=e.target,n=T().contains(t)||O.contains(t);if("mousemove"!==e.type||!n){var o=Q().concat(O).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:l}:null})).filter(Boolean);(function(e,t){var n=t.clientX,o=t.clientY;return e.every((function(e){var t=e.popperRect,r=e.popperState,i=e.props.interactiveBorder,a=Ce(r.placement),s=r.modifiersData.offset;if(!s)return!0;var c="bottom"===a?s.top.y:0,u="top"===a?s.bottom.y:0,l="right"===a?s.left.x:0,d="left"===a?s.right.x:0,p=t.top-o+c>i,f=o-t.bottom-u>i,h=t.left-n+l>i,v=n-t.right-d>i;return p||f||h||v}))})(o,e)&&(R(),te(e))}}function Y(e){X(e)||y.props.trigger.indexOf("click")>=0&&d||(y.props.interactive?y.hideWithInteractivity(e):te(e))}function K(e){y.props.trigger.indexOf("focusin")<0&&e.target!==T()||y.props.interactive&&e.relatedTarget&&O.contains(e.relatedTarget)||te(e)}function X(e){return!!Ge.isTouch&&S()!==e.type.indexOf("touch")>=0}function Z(){J();var t=y.props,n=t.popperOptions,o=t.placement,r=t.offset,i=t.getReferenceClientRect,a=t.moveTransition,c=A()?rt(O).arrow:null,u=i?{getBoundingClientRect:i,contextElement:i.contextElement||T()}:e,l={name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(A()){var n=P().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}},d=[{name:"offset",options:{offset:r}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!a}},l];A()&&c&&d.push({name:"arrow",options:{element:c,padding:3}}),d.push.apply(d,(null==n?void 0:n.modifiers)||[]),y.popperInstance=ge(u,O,Object.assign({},n,{placement:o,onFirstUpdate:s,modifiers:d}))}function J(){y.popperInstance&&(y.popperInstance.destroy(),y.popperInstance=null)}function Q(){return Le(O.querySelectorAll("[data-tippy-root]"))}function ee(e){y.clearDelayTimeouts(),e&&M("onTrigger",[y,e]),H();var t=C(!0),o=j(),r=o[0],i=o[1];Ge.isTouch&&"hold"===r&&i&&(t=i),t?n=setTimeout((function(){y.show()}),t):y.show()}function te(e){if(y.clearDelayTimeouts(),M("onUntrigger",[y,e]),y.state.isVisible){if(!(y.props.trigger.indexOf("mouseenter")>=0&&y.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&d)){var t=C(!1);t?o=setTimeout((function(){y.state.isVisible&&y.hide()}),t):r=requestAnimationFrame((function(){y.hide()}))}}else W()}}function lt(e,t){void 0===t&&(t={});var n=Ze.plugins.concat(t.plugins||[]);document.addEventListener("touchstart",Ue,Ee),window.addEventListener("blur",Ye);var o=Object.assign({},t,{plugins:n}),r=_e(e).reduce((function(e,t){var n=t&&ut(t,o);return n&&e.push(n),e}),[]);return Be(e)?r[0]:r}lt.defaultProps=Ze,lt.setDefaultProps=function(e){Object.keys(e).forEach((function(t){Ze[t]=e[t]}))},lt.currentInput=Ge;Object.assign({},Q,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}});lt.setDefaultProps({render:it});const dt=lt;var pt=n(379),ft=n.n(pt),ht=n(607),vt={insert:"head",singleton:!1};ft()(ht.Z,vt);ht.Z.locals;function mt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function bt(e){for(var t=1;t=0&&yt.splice(n,1)}},Ot=[],xt=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.body;Array.from(e.querySelectorAll("[data-tippy-content], [data-tippy-hover]")).forEach((function(e){var t=bt({},wt);e.getAttribute("data-tippy-hover")&&(t.touch="hold",t.trigger="mouseenter",t.content=function(e){return e.dataset.tippyHover}),e._tippy?e._tippy.setProps(t):Ot.push(dt(e,t))}))};function Et(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function kt(e){return e instanceof Et(e).Element||e instanceof Element}function jt(e){return e instanceof Et(e).HTMLElement||e instanceof HTMLElement}function St(e){return"undefined"!=typeof ShadowRoot&&(e instanceof Et(e).ShadowRoot||e instanceof ShadowRoot)}xt(),window.tooltipSettings=wt,window.initTippy=xt,window.destroyTippy=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.body;e.querySelectorAll("[data-tippy-content], [data-tippy-hover]").forEach((function(e){e._tippy?e.parentNode||e._tippy.destroy():console.error("Tippy tooltip instance not found. Ensure all tippy instances are properly initialized.",e)}))},document.addEventListener("scroll",(function(){return yt.forEach((function(e){return e.hide(0)}))})),window.initClipboard=function(){dt(".clipboard",{trigger:"click",content:function(e){return e.getAttribute("tooltip-content")},onShow:function(e){setTimeout((function(){e.hide()}),3e3)}})},"undefined"!=typeof Livewire&&Livewire.hook("message.processed",(function(e,t){t.el,Ot=Ot.reduce((function(e,t){var n=t.reference;return n.parentNode&&(n.getAttribute("data-tippy-hover")||n.getAttribute("data-tippy-content"))?e.push(t):t.destroy(),e}),[]),xt(t.el)})),window.tippy=dt;var At=Math.max,Tt=Math.min,Dt=Math.round;function Pt(){var e=navigator.userAgentData;return null!=e&&e.brands?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function Ct(){return!/^((?!chrome|android).)*safari/i.test(Pt())}function Lt(e,t,n){void 0===t&&(t=!1),void 0===n&&(n=!1);var o=e.getBoundingClientRect(),r=1,i=1;t&&jt(e)&&(r=e.offsetWidth>0&&Dt(o.width)/e.offsetWidth||1,i=e.offsetHeight>0&&Dt(o.height)/e.offsetHeight||1);var a=(kt(e)?Et(e):window).visualViewport,s=!Ct()&&n,c=(o.left+(s&&a?a.offsetLeft:0))/r,u=(o.top+(s&&a?a.offsetTop:0))/i,l=o.width/r,d=o.height/i;return{width:l,height:d,top:u,right:c+l,bottom:u+d,left:c,x:c,y:u}}function Mt(e){var t=Et(e);return{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function Nt(e){return e?(e.nodeName||"").toLowerCase():null}function Bt(e){return((kt(e)?e.ownerDocument:e.document)||window.document).documentElement}function Rt(e){return Lt(Bt(e)).left+Mt(e).scrollLeft}function It(e){return Et(e).getComputedStyle(e)}function _t(e){var t=It(e),n=t.overflow,o=t.overflowX,r=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+r+o)}function Ft(e,t,n){void 0===n&&(n=!1);var o,r,i=jt(t),a=jt(t)&&function(e){var t=e.getBoundingClientRect(),n=Dt(t.width)/e.offsetWidth||1,o=Dt(t.height)/e.offsetHeight||1;return 1!==n||1!==o}(t),s=Bt(t),c=Lt(e,a,n),u={scrollLeft:0,scrollTop:0},l={x:0,y:0};return(i||!i&&!n)&&(("body"!==Nt(t)||_t(s))&&(u=(o=t)!==Et(o)&&jt(o)?{scrollLeft:(r=o).scrollLeft,scrollTop:r.scrollTop}:Mt(o)),jt(t)?((l=Lt(t,!0)).x+=t.clientLeft,l.y+=t.clientTop):s&&(l.x=Rt(s))),{x:c.left+u.scrollLeft-l.x,y:c.top+u.scrollTop-l.y,width:c.width,height:c.height}}function Ht(e){var t=Lt(e),n=e.offsetWidth,o=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-o)<=1&&(o=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:o}}function Wt(e){return"html"===Nt(e)?e:e.assignedSlot||e.parentNode||(St(e)?e.host:null)||Bt(e)}function qt(e){return["html","body","#document"].indexOf(Nt(e))>=0?e.ownerDocument.body:jt(e)&&_t(e)?e:qt(Wt(e))}function Vt(e,t){var n;void 0===t&&(t=[]);var o=qt(e),r=o===(null==(n=e.ownerDocument)?void 0:n.body),i=Et(o),a=r?[i].concat(i.visualViewport||[],_t(o)?o:[]):o,s=t.concat(a);return r?s:s.concat(Vt(Wt(a)))}function Gt(e){return["table","td","th"].indexOf(Nt(e))>=0}function $t(e){return jt(e)&&"fixed"!==It(e).position?e.offsetParent:null}function Ut(e){for(var t=Et(e),n=$t(e);n&&Gt(n)&&"static"===It(n).position;)n=$t(n);return n&&("html"===Nt(n)||"body"===Nt(n)&&"static"===It(n).position)?t:n||function(e){var t=/firefox/i.test(Pt());if(/Trident/i.test(Pt())&&jt(e)&&"fixed"===It(e).position)return null;var n=Wt(e);for(St(n)&&(n=n.host);jt(n)&&["html","body"].indexOf(Nt(n))<0;){var o=It(n);if("none"!==o.transform||"none"!==o.perspective||"paint"===o.contain||-1!==["transform","perspective"].indexOf(o.willChange)||t&&"filter"===o.willChange||t&&o.filter&&"none"!==o.filter)return n;n=n.parentNode}return null}(e)||t}var zt="top",Yt="bottom",Kt="right",Xt="left",Zt="auto",Jt=[zt,Yt,Kt,Xt],Qt="start",en="end",tn="viewport",nn="popper",on=Jt.reduce((function(e,t){return e.concat([t+"-"+Qt,t+"-"+en])}),[]),rn=[].concat(Jt,[Zt]).reduce((function(e,t){return e.concat([t,t+"-"+Qt,t+"-"+en])}),[]),an=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function sn(e){var t=new Map,n=new Set,o=[];function r(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var o=t.get(e);o&&r(o)}})),o.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||r(e)})),o}var cn={placement:"bottom",modifiers:[],strategy:"absolute"};function un(){for(var e=arguments.length,t=new Array(e),n=0;n=0?"x":"y"}function mn(e){var t,n=e.reference,o=e.element,r=e.placement,i=r?fn(r):null,a=r?hn(r):null,s=n.x+n.width/2-o.width/2,c=n.y+n.height/2-o.height/2;switch(i){case zt:t={x:s,y:n.y-o.height};break;case Yt:t={x:s,y:n.y+n.height};break;case Kt:t={x:n.x+n.width,y:c};break;case Xt:t={x:n.x-o.width,y:c};break;default:t={x:n.x,y:n.y}}var u=i?vn(i):null;if(null!=u){var l="y"===u?"height":"width";switch(a){case Qt:t[u]=t[u]-(n[l]/2-o[l]/2);break;case en:t[u]=t[u]+(n[l]/2-o[l]/2)}}return t}var bn={top:"auto",right:"auto",bottom:"auto",left:"auto"};function gn(e){var t,n=e.popper,o=e.popperRect,r=e.placement,i=e.variation,a=e.offsets,s=e.position,c=e.gpuAcceleration,u=e.adaptive,l=e.roundOffsets,d=e.isFixed,p=a.x,f=void 0===p?0:p,h=a.y,v=void 0===h?0:h,m="function"==typeof l?l({x:f,y:v}):{x:f,y:v};f=m.x,v=m.y;var b=a.hasOwnProperty("x"),g=a.hasOwnProperty("y"),y=Xt,w=zt,O=window;if(u){var x=Ut(n),E="clientHeight",k="clientWidth";if(x===Et(n)&&"static"!==It(x=Bt(n)).position&&"absolute"===s&&(E="scrollHeight",k="scrollWidth"),x=x,r===zt||(r===Xt||r===Kt)&&i===en)w=Yt,v-=(d&&x===O&&O.visualViewport?O.visualViewport.height:x[E])-o.height,v*=c?1:-1;if(r===Xt||(r===zt||r===Yt)&&i===en)y=Kt,f-=(d&&x===O&&O.visualViewport?O.visualViewport.width:x[k])-o.width,f*=c?1:-1}var j,S=Object.assign({position:s},u&&bn),A=!0===l?function(e){var t=e.x,n=e.y,o=window.devicePixelRatio||1;return{x:Dt(t*o)/o||0,y:Dt(n*o)/o||0}}({x:f,y:v}):{x:f,y:v};return f=A.x,v=A.y,c?Object.assign({},S,((j={})[w]=g?"0":"",j[y]=b?"0":"",j.transform=(O.devicePixelRatio||1)<=1?"translate("+f+"px, "+v+"px)":"translate3d("+f+"px, "+v+"px, 0)",j)):Object.assign({},S,((t={})[w]=g?v+"px":"",t[y]=b?f+"px":"",t.transform="",t))}const yn={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,o=n.gpuAcceleration,r=void 0===o||o,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,c=void 0===s||s,u={placement:fn(t.placement),variation:hn(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:r,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,gn(Object.assign({},u,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:c})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,gn(Object.assign({},u,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:c})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};const wn={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.offset,i=void 0===r?[0,0]:r,a=rn.reduce((function(e,n){return e[n]=function(e,t,n){var o=fn(e),r=[Xt,zt].indexOf(o)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*r,[Xt,Kt].indexOf(o)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],c=s.x,u=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=c,t.modifiersData.popperOffsets.y+=u),t.modifiersData[o]=a}};var On={left:"right",right:"left",bottom:"top",top:"bottom"};function xn(e){return e.replace(/left|right|bottom|top/g,(function(e){return On[e]}))}var En={start:"end",end:"start"};function kn(e){return e.replace(/start|end/g,(function(e){return En[e]}))}function jn(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&St(n)){var o=t;do{if(o&&e.isSameNode(o))return!0;o=o.parentNode||o.host}while(o)}return!1}function Sn(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function An(e,t,n){return t===tn?Sn(function(e,t){var n=Et(e),o=Bt(e),r=n.visualViewport,i=o.clientWidth,a=o.clientHeight,s=0,c=0;if(r){i=r.width,a=r.height;var u=Ct();(u||!u&&"fixed"===t)&&(s=r.offsetLeft,c=r.offsetTop)}return{width:i,height:a,x:s+Rt(e),y:c}}(e,n)):kt(t)?function(e,t){var n=Lt(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(t,n):Sn(function(e){var t,n=Bt(e),o=Mt(e),r=null==(t=e.ownerDocument)?void 0:t.body,i=At(n.scrollWidth,n.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),a=At(n.scrollHeight,n.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),s=-o.scrollLeft+Rt(e),c=-o.scrollTop;return"rtl"===It(r||n).direction&&(s+=At(n.clientWidth,r?r.clientWidth:0)-i),{width:i,height:a,x:s,y:c}}(Bt(e)))}function Tn(e,t,n,o){var r="clippingParents"===t?function(e){var t=Vt(Wt(e)),n=["absolute","fixed"].indexOf(It(e).position)>=0&&jt(e)?Ut(e):e;return kt(n)?t.filter((function(e){return kt(e)&&jn(e,n)&&"body"!==Nt(e)})):[]}(e):[].concat(t),i=[].concat(r,[n]),a=i[0],s=i.reduce((function(t,n){var r=An(e,n,o);return t.top=At(r.top,t.top),t.right=Tt(r.right,t.right),t.bottom=Tt(r.bottom,t.bottom),t.left=At(r.left,t.left),t}),An(e,a,o));return s.width=s.right-s.left,s.height=s.bottom-s.top,s.x=s.left,s.y=s.top,s}function Dn(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function Pn(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Cn(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=void 0===o?e.placement:o,i=n.strategy,a=void 0===i?e.strategy:i,s=n.boundary,c=void 0===s?"clippingParents":s,u=n.rootBoundary,l=void 0===u?tn:u,d=n.elementContext,p=void 0===d?nn:d,f=n.altBoundary,h=void 0!==f&&f,v=n.padding,m=void 0===v?0:v,b=Dn("number"!=typeof m?m:Pn(m,Jt)),g=p===nn?"reference":nn,y=e.rects.popper,w=e.elements[h?g:p],O=Tn(kt(w)?w:w.contextElement||Bt(e.elements.popper),c,l,a),x=Lt(e.elements.reference),E=mn({reference:x,element:y,strategy:"absolute",placement:r}),k=Sn(Object.assign({},y,E)),j=p===nn?k:x,S={top:O.top-j.top+b.top,bottom:j.bottom-O.bottom+b.bottom,left:O.left-j.left+b.left,right:j.right-O.right+b.right},A=e.modifiersData.offset;if(p===nn&&A){var T=A[r];Object.keys(S).forEach((function(e){var t=[Kt,Yt].indexOf(e)>=0?1:-1,n=[zt,Yt].indexOf(e)>=0?"y":"x";S[e]+=T[n]*t}))}return S}const Ln={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name;if(!t.modifiersData[o]._skip){for(var r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0===a||a,c=n.fallbackPlacements,u=n.padding,l=n.boundary,d=n.rootBoundary,p=n.altBoundary,f=n.flipVariations,h=void 0===f||f,v=n.allowedAutoPlacements,m=t.options.placement,b=fn(m),g=c||(b===m||!h?[xn(m)]:function(e){if(fn(e)===Zt)return[];var t=xn(e);return[kn(e),t,kn(t)]}(m)),y=[m].concat(g).reduce((function(e,n){return e.concat(fn(n)===Zt?function(e,t){void 0===t&&(t={});var n=t,o=n.placement,r=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,c=n.allowedAutoPlacements,u=void 0===c?rn:c,l=hn(o),d=l?s?on:on.filter((function(e){return hn(e)===l})):Jt,p=d.filter((function(e){return u.indexOf(e)>=0}));0===p.length&&(p=d);var f=p.reduce((function(t,n){return t[n]=Cn(e,{placement:n,boundary:r,rootBoundary:i,padding:a})[fn(n)],t}),{});return Object.keys(f).sort((function(e,t){return f[e]-f[t]}))}(t,{placement:n,boundary:l,rootBoundary:d,padding:u,flipVariations:h,allowedAutoPlacements:v}):n)}),[]),w=t.rects.reference,O=t.rects.popper,x=new Map,E=!0,k=y[0],j=0;j=0,P=D?"width":"height",C=Cn(t,{placement:S,boundary:l,rootBoundary:d,altBoundary:p,padding:u}),L=D?T?Kt:Xt:T?Yt:zt;w[P]>O[P]&&(L=xn(L));var M=xn(L),N=[];if(i&&N.push(C[A]<=0),s&&N.push(C[L]<=0,C[M]<=0),N.every((function(e){return e}))){k=S,E=!1;break}x.set(S,N)}if(E)for(var B=function(e){var t=y.find((function(t){var n=x.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},R=h?3:1;R>0;R--){if("break"===B(R))break}t.placement!==k&&(t.modifiersData[o]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Mn(e,t,n){return At(e,Tt(t,n))}const Nn={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,o=e.name,r=n.mainAxis,i=void 0===r||r,a=n.altAxis,s=void 0!==a&&a,c=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,p=n.tether,f=void 0===p||p,h=n.tetherOffset,v=void 0===h?0:h,m=Cn(t,{boundary:c,rootBoundary:u,padding:d,altBoundary:l}),b=fn(t.placement),g=hn(t.placement),y=!g,w=vn(b),O="x"===w?"y":"x",x=t.modifiersData.popperOffsets,E=t.rects.reference,k=t.rects.popper,j="function"==typeof v?v(Object.assign({},t.rects,{placement:t.placement})):v,S="number"==typeof j?{mainAxis:j,altAxis:j}:Object.assign({mainAxis:0,altAxis:0},j),A=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,T={x:0,y:0};if(x){if(i){var D,P="y"===w?zt:Xt,C="y"===w?Yt:Kt,L="y"===w?"height":"width",M=x[w],N=M+m[P],B=M-m[C],R=f?-k[L]/2:0,I=g===Qt?E[L]:k[L],_=g===Qt?-k[L]:-E[L],F=t.elements.arrow,H=f&&F?Ht(F):{width:0,height:0},W=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},q=W[P],V=W[C],G=Mn(0,E[L],H[L]),$=y?E[L]/2-R-G-q-S.mainAxis:I-G-q-S.mainAxis,U=y?-E[L]/2+R+G+V+S.mainAxis:_+G+V+S.mainAxis,z=t.elements.arrow&&Ut(t.elements.arrow),Y=z?"y"===w?z.clientTop||0:z.clientLeft||0:0,K=null!=(D=null==A?void 0:A[w])?D:0,X=M+U-K,Z=Mn(f?Tt(N,M+$-K-Y):N,M,f?At(B,X):B);x[w]=Z,T[w]=Z-M}if(s){var J,Q="x"===w?zt:Xt,ee="x"===w?Yt:Kt,te=x[O],ne="y"===O?"height":"width",oe=te+m[Q],re=te-m[ee],ie=-1!==[zt,Xt].indexOf(b),ae=null!=(J=null==A?void 0:A[O])?J:0,se=ie?oe:te-E[ne]-k[ne]-ae+S.altAxis,ce=ie?te+E[ne]+k[ne]-ae-S.altAxis:re,ue=f&&ie?function(e,t,n){var o=Mn(e,t,n);return o>n?n:o}(se,te,ce):Mn(f?se:oe,te,f?ce:re);x[O]=ue,T[O]=ue-te}t.modifiersData[o]=T}},requiresIfExists:["offset"]};const Bn={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,o=e.name,r=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=fn(n.placement),c=vn(s),u=[Xt,Kt].indexOf(s)>=0?"height":"width";if(i&&a){var l=function(e,t){return Dn("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:Pn(e,Jt))}(r.padding,n),d=Ht(i),p="y"===c?zt:Xt,f="y"===c?Yt:Kt,h=n.rects.reference[u]+n.rects.reference[c]-a[c]-n.rects.popper[u],v=a[c]-n.rects.reference[c],m=Ut(i),b=m?"y"===c?m.clientHeight||0:m.clientWidth||0:0,g=h/2-v/2,y=l[p],w=b-d[u]-l[f],O=b/2-d[u]/2+g,x=Mn(y,O,w),E=c;n.modifiersData[o]=((t={})[E]=x,t.centerOffset=x-O,t)}},effect:function(e){var t=e.state,n=e.options.element,o=void 0===n?"[data-popper-arrow]":n;null!=o&&("string"!=typeof o||(o=t.elements.popper.querySelector(o)))&&jn(t.elements.popper,o)&&(t.elements.arrow=o)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Rn(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function In(e){return[zt,Kt,Yt,Xt].some((function(t){return e[t]>=0}))}var _n=ln({defaultModifiers:[pn,{name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=mn({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},yn,{name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];jt(r)&&Nt(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});jt(o)&&Nt(o)&&(Object.assign(o.style,i),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]},wn,Ln,Nn,Bn,{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,o=t.rects.reference,r=t.rects.popper,i=t.modifiersData.preventOverflow,a=Cn(t,{elementContext:"reference"}),s=Cn(t,{altBoundary:!0}),c=Rn(a,o),u=Rn(s,r,i),l=In(c),d=In(u);t.modifiersData[n]={referenceClippingOffsets:c,popperEscapeOffsets:u,isReferenceHidden:l,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":l,"data-popper-escaped":d})}}]});function Fn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Hn(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:qn.defaultSettings;e.onOpened&&e.onOpened(this.$el)},onClosed:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:qn.defaultSettings;e.onClosed&&e.onClosed(this.$el)},setup:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"dropdownOpen",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:qn.defaultSettings;t=Hn(Hn({},qn.defaultSettings),t);var n={propertyName:e,popperInstance:null,update:function(){this[this.propertyName]&&this.popperInstance.update()},preAdjustDropdownPosition:function(e){e.style.opacity="0",e.style.display="block",this.update(),e.style.removeProperty("opacity"),e.style.removeProperty("display")},toggle:function(){this[this.propertyName]=!this[this.propertyName]},close:function(){this[this.propertyName]=!1},open:function(){this[this.propertyName]=!0},init:function(){var n=this,o=this.$el,r=o.querySelector(".dropdown"),i=o.querySelector(".dropdown-button");this.popperInstance=_n(i,r,{strategy:"fixed",placement:t.placement,modifiers:[{name:"preventOverflow"},{name:"offset",options:{offset:t.offset}}]}),this.$watch(e,(function(e){e?(n.preAdjustDropdownPosition(r),n.$nextTick((function(){n.update(),qn.onOpened.call(n,t)}))):n.$nextTick((function(){qn.onClosed.call(n,t)}))}))}};return n[e]=!1,n}};const Vn=qn;var Gn=!1;if("undefined"!=typeof window){var $n={get passive(){Gn=!0}};window.addEventListener("testPassive",null,$n),window.removeEventListener("testPassive",null,$n)}var Un="undefined"!=typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1),zn=[],Yn=!1,Kn=-1,Xn=void 0,Zn=void 0,Jn=function(e){return zn.some((function(t){return!(!t.options.allowTouchMove||!t.options.allowTouchMove(e))}))},Qn=function(e){var t=e||window.event;return!!Jn(t.target)||(t.touches.length>1||(t.preventDefault&&t.preventDefault(),!1))},eo=function(){void 0!==Zn&&(document.body.style.paddingRight=Zn,Zn=void 0),void 0!==Xn&&(document.body.style.overflow=Xn,Xn=void 0)},to=function(e,t){if(e){if(!zn.some((function(t){return t.targetElement===e}))){var n={targetElement:e,options:t||{}};zn=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t0||function(e){return!!e&&e.scrollHeight-e.scrollTop<=e.clientHeight}(t)&&n<0?Qn(e):e.stopPropagation())}(t,e)},Yn||(document.addEventListener("touchmove",Qn,Gn?{passive:!1}:void 0),Yn=!0)):function(e){if(void 0===Zn){var t=!!e&&!0===e.reserveScrollBarGap,n=window.innerWidth-document.documentElement.clientWidth;t&&n>0&&(Zn=document.body.style.paddingRight,document.body.style.paddingRight=n+"px")}void 0===Xn&&(Xn=document.body.style.overflow,document.body.style.overflow="hidden")}(t)}}else console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},no=function(){Un?(zn.forEach((function(e){e.targetElement.ontouchstart=null,e.targetElement.ontouchmove=null})),Yn&&(document.removeEventListener("touchmove",Qn,Gn?{passive:!1}:void 0),Yn=!1),Kn=-1):eo(),zn=[]},oo=function(e){e?(zn=zn.filter((function(t){return t.targetElement!==e})),Un?(e.ontouchstart=null,e.ontouchmove=null,Yn&&0===zn.length&&(document.removeEventListener("touchmove",Qn,Gn?{passive:!1}:void 0),Yn=!1)):zn.length||eo()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")},ro=["input","select","textarea","a[href]","button","[tabindex]:not(slot)","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable="false"])',"details>summary:first-of-type","details"],io=ro.join(","),ao="undefined"==typeof Element,so=ao?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,co=!ao&&Element.prototype.getRootNode?function(e){return e.getRootNode()}:function(e){return e.ownerDocument},uo=function(e,t,n){var o=Array.prototype.slice.apply(e.querySelectorAll(io));return t&&so.call(e,io)&&o.unshift(e),o=o.filter(n)},lo=function e(t,n,o){for(var r=[],i=Array.from(t);i.length;){var a=i.shift();if("SLOT"===a.tagName){var s=a.assignedElements(),c=e(s.length?s:a.children,!0,o);o.flatten?r.push.apply(r,c):r.push({scope:a,candidates:c})}else{so.call(a,io)&&o.filter(a)&&(n||!t.includes(a))&&r.push(a);var u=a.shadowRoot||"function"==typeof o.getShadowRoot&&o.getShadowRoot(a),l=!o.shadowRootFilter||o.shadowRootFilter(a);if(u&&l){var d=e(!0===u?a.children:u.children,!0,o);o.flatten?r.push.apply(r,d):r.push({scope:a,candidates:d})}else i.unshift.apply(i,a.children)}}return r},po=function(e,t){return e.tabIndex<0&&(t||/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||e.isContentEditable)&&isNaN(parseInt(e.getAttribute("tabindex"),10))?0:e.tabIndex},fo=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},ho=function(e){return"INPUT"===e.tagName},vo=function(e){return function(e){return ho(e)&&"radio"===e.type}(e)&&!function(e){if(!e.name)return!0;var t,n=e.form||co(e),o=function(e){return n.querySelectorAll('input[type="radio"][name="'+e+'"]')};if("undefined"!=typeof window&&void 0!==window.CSS&&"function"==typeof window.CSS.escape)t=o(window.CSS.escape(e.name));else try{t=o(e.name)}catch(e){return console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s",e.message),!1}var r=function(e,t){for(var n=0;nsummary:first-of-type")?e.parentElement:e;if(so.call(r,"details:not([open]) *"))return!0;var i=co(e).host,a=(null==i?void 0:i.ownerDocument.contains(i))||e.ownerDocument.contains(e);if(n&&"full"!==n){if("non-zero-area"===n)return mo(e)}else{if("function"==typeof o){for(var s=e;e;){var c=e.parentElement,u=co(e);if(c&&!c.shadowRoot&&!0===o(c))return mo(e);e=e.assignedSlot?e.assignedSlot:c||u===e.ownerDocument?c:u.host}e=s}if(a)return!e.getClientRects().length}return!1}(t,e)||function(e){return"DETAILS"===e.tagName&&Array.prototype.slice.apply(e.children).some((function(e){return"SUMMARY"===e.tagName}))}(t)||function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if("FIELDSET"===t.tagName&&t.disabled){for(var n=0;n=0)},wo=function e(t){var n=[],o=[];return t.forEach((function(t,r){var i=!!t.scope,a=i?t.scope:t,s=po(a,i),c=i?e(t.candidates):a;0===s?i?n.push.apply(n,c):n.push(a):o.push({documentOrder:r,tabIndex:s,item:t,isScope:i,content:c})})),o.sort(fo).reduce((function(e,t){return t.isScope?e.push.apply(e,t.content):e.push(t.content),e}),[]).concat(n)},Oo=function(e,t){var n;return n=(t=t||{}).getShadowRoot?lo([e],t.includeContainer,{filter:go.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:yo}):uo(e,t.includeContainer,go.bind(null,t)),wo(n)},xo=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return!1!==so.call(e,io)&&go(t,e)},Eo=ro.concat("iframe").join(","),ko=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return!1!==so.call(e,Eo)&&bo(t,e)};function jo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function So(e){for(var t=1;t0){var t=To[To.length-1];t!==e&&t.pause()}var n=To.indexOf(e);-1===n||To.splice(n,1),To.push(e)},deactivateTrap:function(e){var t=To.indexOf(e);-1!==t&&To.splice(t,1),To.length>0&&To[To.length-1].unpause()}}),Po=function(e){return setTimeout(e,0)},Co=function(e,t){var n=-1;return e.every((function(e,o){return!t(e)||(n=o,!1)})),n},Lo=function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),o=1;o1?n-1:0),a=1;a=0)e=o.activeElement;else{var t=i.tabbableGroups[0];e=t&&t.firstTabbableNode||c("fallbackFocus")}if(!e)throw new Error("Your focus-trap needs to have at least one focusable element");return e},l=function(){if(i.containerGroups=i.containers.map((function(e){var t=Oo(e,r.tabbableOptions),n=function(e,t){return(t=t||{}).getShadowRoot?lo([e],t.includeContainer,{filter:bo.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):uo(e,t.includeContainer,bo.bind(null,t))}(e,r.tabbableOptions);return{container:e,tabbableNodes:t,focusableNodes:n,firstTabbableNode:t.length>0?t[0]:null,lastTabbableNode:t.length>0?t[t.length-1]:null,nextTabbableNode:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],o=n.findIndex((function(t){return t===e}));if(!(o<0))return t?n.slice(o+1).find((function(e){return xo(e,r.tabbableOptions)})):n.slice(0,o).reverse().find((function(e){return xo(e,r.tabbableOptions)}))}}})),i.tabbableGroups=i.containerGroups.filter((function(e){return e.tabbableNodes.length>0})),i.tabbableGroups.length<=0&&!c("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times")},d=function e(t){!1!==t&&t!==o.activeElement&&(t&&t.focus?(t.focus({preventScroll:!!r.preventScroll}),i.mostRecentlyFocusedNode=t,function(e){return e.tagName&&"input"===e.tagName.toLowerCase()&&"function"==typeof e.select}(t)&&t.select()):e(u()))},p=function(e){var t=c("setReturnFocus",e);return t||!1!==t&&e},f=function(e){var t=Mo(e);s(t)>=0||(Lo(r.clickOutsideDeactivates,e)?n.deactivate({returnFocus:r.returnFocusOnDeactivate&&!ko(t,r.tabbableOptions)}):Lo(r.allowOutsideClick,e)||e.preventDefault())},h=function(e){var t=Mo(e),n=s(t)>=0;n||t instanceof Document?n&&(i.mostRecentlyFocusedNode=t):(e.stopImmediatePropagation(),d(i.mostRecentlyFocusedNode||u()))},v=function(e){if(function(e){return"Escape"===e.key||"Esc"===e.key||27===e.keyCode}(e)&&!1!==Lo(r.escapeDeactivates,e))return e.preventDefault(),void n.deactivate();(function(e){return"Tab"===e.key||9===e.keyCode})(e)&&function(e){var t=Mo(e);l();var n=null;if(i.tabbableGroups.length>0){var o=s(t),a=o>=0?i.containerGroups[o]:void 0;if(o<0)n=e.shiftKey?i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:i.tabbableGroups[0].firstTabbableNode;else if(e.shiftKey){var u=Co(i.tabbableGroups,(function(e){var n=e.firstTabbableNode;return t===n}));if(u<0&&(a.container===t||ko(t,r.tabbableOptions)&&!xo(t,r.tabbableOptions)&&!a.nextTabbableNode(t,!1))&&(u=o),u>=0){var p=0===u?i.tabbableGroups.length-1:u-1;n=i.tabbableGroups[p].lastTabbableNode}}else{var f=Co(i.tabbableGroups,(function(e){var n=e.lastTabbableNode;return t===n}));if(f<0&&(a.container===t||ko(t,r.tabbableOptions)&&!xo(t,r.tabbableOptions)&&!a.nextTabbableNode(t))&&(f=o),f>=0){var h=f===i.tabbableGroups.length-1?0:f+1;n=i.tabbableGroups[h].firstTabbableNode}}}else n=c("fallbackFocus");n&&(e.preventDefault(),d(n))}(e)},m=function(e){var t=Mo(e);s(t)>=0||Lo(r.clickOutsideDeactivates,e)||Lo(r.allowOutsideClick,e)||(e.preventDefault(),e.stopImmediatePropagation())},b=function(){if(i.active)return Do.activateTrap(n),i.delayInitialFocusTimer=r.delayInitialFocus?Po((function(){d(u())})):d(u()),o.addEventListener("focusin",h,!0),o.addEventListener("mousedown",f,{capture:!0,passive:!1}),o.addEventListener("touchstart",f,{capture:!0,passive:!1}),o.addEventListener("click",m,{capture:!0,passive:!1}),o.addEventListener("keydown",v,{capture:!0,passive:!1}),n},g=function(){if(i.active)return o.removeEventListener("focusin",h,!0),o.removeEventListener("mousedown",f,!0),o.removeEventListener("touchstart",f,!0),o.removeEventListener("click",m,!0),o.removeEventListener("keydown",v,!0),n};return n={get active(){return i.active},get paused(){return i.paused},activate:function(e){if(i.active)return this;var t=a(e,"onActivate"),n=a(e,"onPostActivate"),r=a(e,"checkCanFocusTrap");r||l(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=o.activeElement,t&&t();var s=function(){r&&l(),b(),n&&n()};return r?(r(i.containers.concat()).then(s,s),this):(s(),this)},deactivate:function(e){if(!i.active)return this;var t=So({onDeactivate:r.onDeactivate,onPostDeactivate:r.onPostDeactivate,checkCanReturnFocus:r.checkCanReturnFocus},e);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,g(),i.active=!1,i.paused=!1,Do.deactivateTrap(n);var o=a(t,"onDeactivate"),s=a(t,"onPostDeactivate"),c=a(t,"checkCanReturnFocus"),u=a(t,"returnFocus","returnFocusOnDeactivate");o&&o();var l=function(){Po((function(){u&&d(p(i.nodeFocusedBeforeActivation)),s&&s()}))};return u&&c?(c(p(i.nodeFocusedBeforeActivation)).then(l,l),this):(l(),this)},pause:function(){return i.paused||!i.active||(i.paused=!0,g()),this},unpause:function(){return i.paused&&i.active?(i.paused=!1,l(),b(),this):this},updateContainerElements:function(e){var t=[].concat(e).filter(Boolean);return i.containers=t.map((function(e){return"string"==typeof e?o.querySelector(e):e})),i.active&&l(),this}},n.updateContainerElements(e),n};function Bo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Ro(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{};(t=Object.assign({},this.defaultSettings,t)).reserveScrollBarGap&&this.reserveModalScrollBarGap(e),t.reserveNavScrollBarGap&&this.reserveNavScrollBarGap(e),to(e,{reserveScrollBarGap:!!t.reserveScrollBarGap})},enableBodyScroll:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};(t=Object.assign({},this.defaultSettings,t)).reserveScrollBarGap&&this.restoreModalScrollBarGap(e),t.reserveNavScrollBarGap&&this.restoreNavScrollBarGap(e),oo(e)},onModalOpened:function(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.disableBodyScroll(e,n),setTimeout((function(){n.disableFocusTrap?e.focus():t.trapFocus(e)}),50)},onModalClosed:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.enableBodyScroll(e,t),this.releaseTrappedFocus(),document.querySelectorAll("[data-modal]").length||no()},trapFocus:function(e){if(this.trappedElement!==e){this.releaseTrappedFocus();var t=No(e,{escapeDeactivates:!1,allowOutsideClick:!0,fallbackFocus:e.querySelector("input:not([type=hidden])")});this.trappedFocus=t.activate(),this.trappedElement=e}},releaseTrappedFocus:function(){this.trappedFocus&&(this.trappedFocus.deactivate(),this.trappedFocus=null,this.trappedElement=null)},alpine:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return Ro({name:t,shown:!1,onBeforeHide:!1,onBeforeShow:!1,onHidden:!1,onShown:!1,options:null,init:function(){var e=this,t=this.getScrollable();this.name&&(Livewire.on("openModal",(function(t){if(e.name===t){for(var n=arguments.length,o=new Array(n>1?n-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Ro({init:function(){var e=this,n=this.getScrollable();this.$wire.on("modalClosed",(function(){e.$nextTick((function(){_o.onModalClosed(n,t)}))})),_o.onModalOpened(n,t)},getScrollable:function(){return this.$refs.modal}},e)},reserveModalScrollBarGap:function(e){if(void 0===this.previousPaddingRight){var t=window.innerWidth-document.documentElement.clientWidth;if(t>0){var n=parseInt(window.getComputedStyle(e).getPropertyValue("padding-right"),10);this.previousPaddingRight=e.style.paddingRight,e.style.paddingRight="".concat(n+t,"px")}}},restoreModalScrollBarGap:function(e){void 0!==this.previousPaddingRight&&(e.style.paddingRight=this.previousPaddingRight,this.previousPaddingRight=void 0)},reserveNavScrollBarGap:function(){var e=document.querySelector("header nav");if(void 0===this.previousNavPaddingRight){var t=window.innerWidth-document.documentElement.clientWidth;if(t>0){var n=parseInt(window.getComputedStyle(e).getPropertyValue("padding-right"),10);this.previousNavPaddingRight=e.style.paddingRight,e.style.paddingRight="".concat(n+t,"px")}}},restoreNavScrollBarGap:function(){var e=document.querySelector("header nav");void 0!==this.previousNavPaddingRight&&(e.style.paddingRight=this.previousNavPaddingRight,this.previousNavPaddingRight=void 0)}};const Fo=_o;function Ho(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Wo(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{};return Wo({inverted:!1,invertOnScroll:!1,open:!1,openDropdown:null,selectedChild:null,scrollProgress:0,nav:null,header:null,dark:!1,lockBodyBreakpoint:640,onScroll:function(){var e=this.getScrollProgress();e!==this.scrollProgress&&(this.scrollProgress=e,this.updateStyles(e))},getScrollProgress:function(){var e=document.documentElement.scrollTop,t=this.inverted?20:0,n=this.inverted?50:82;return e=n.top&&o.bottom<=n.bottom&&o.left>=n.left&&o.right<=n.right},disableTabIndexOfInvisibleElements:function(e,t){var n=this;t.forEach((function(t){n.elementIsVisibleIn(e,t)?t.querySelectorAll("[data-custom-tabindex]").forEach((function(e){e.removeAttribute("tabindex"),e.removeAttribute("data-custom-tabindex")})):n.getKeyboardFocusableElements(t).forEach((function(e){e.setAttribute("tabindex","-1"),e.setAttribute("data-custom-tabindex","true")}))}))},setupKeyboardEvents:function(e){e.$el[0].addEventListener("keydown",(function(t){"ArrowRight"===t.code?e.slideNext():"ArrowLeft"===t.code&&e.slidePrev()}))}};const Yo=function(e,t){return{search:!1,page:null,init:function(){var n=this;this.$watch("search",(function(t){t?n.$nextTick((function(){n.$el.querySelectorAll("input[name=".concat(e,"]")).forEach((function(e){e.focus()}))})):n.page=null})),this.$watch("page",(function(e){null!==e&&(e<1&&(n.page=1),e>t&&(n.page=t))}))},blurHandler:function(){this.page||(this.search=!1)},toggleSearch:function(){this.search=!this.search},hideSearch:function(){this.search=!1}}};function Ko(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function Xo(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",r=arguments.length>4&&void 0!==arguments[4]&&arguments[4],i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:void 0;return Xo({options:t,onInput:function(e,t){i&&e(i,t.target.value)},getOptionsCount:function(){var e=this;return null!==this.optionsCount||(this.optionsCount=r?Object.keys(this.options).map((function(t){return Object.keys(e.options[t])})).flat().length:Object.keys(this.options).length),this.optionsCount},defaultPopperOptions:{strategy:"fixed",placement:"bottom-end",modifiers:[{name:"preventOverflow"},{name:"offset",options:{offset:[0,8]}}]},optionsCount:null,open:!1,popperInstance:null,selected:null,selectedGroup:null,value:n,text:o,init:function(){var e=this.$el,t=e.querySelector(".dropdown"),n=e.querySelector(".dropdown-button");this.popperInstance=_n(n,t,Xo(Xo({},this.defaultPopperOptions),this.popperOptions||{}))},choose:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;this.value!==e&&(this.value=e,this.text=null!==t?this.options[t][e]:this.options[e],this.open=!1,this.setHiddenInputValue(e))},setHiddenInputValue:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this.$refs.input;if(n.value=e,t){var o=new Event("input",{bubbles:!0,cancelable:!0});n.dispatchEvent(o)}},onButtonClick:function(){var e,t=this,n=this.$refs.listbox;e=r?this.getAllValues().indexOf(this.value):Object.keys(this.options).indexOf(this.value),this.selected=e>=0?e:0,this.open=!0,this.$nextTick((function(){n.focus(),t.scrollToSelectedOption()}))},onOptionSelect:function(){if(r){var e=this.getAllValues();this.choose(e[this.selected],this.selectedGroup)}else null!==this.selected&&this.choose(Object.keys(this.options)[this.selected]);this.open=!1,this.$refs.button.focus()},onEscape:function(){this.open=!1,this.$refs.button.focus()},onArrowUp:function(){var e=this.getOptionsCount();this.selected=this.selected-1<0?e-1:this.selected-1,this.scrollToSelectedOption()},onArrowDown:function(){var e=this.getOptionsCount();this.selected=this.selected+1>e-1?0:this.selected+1,this.scrollToSelectedOption()},scrollToSelectedOption:function(){var e=this.$refs.listbox.querySelectorAll("[data-option]")[this.selected];r&&(this.selectedGroup=e.dataset.group),e.scrollIntoView({block:"nearest"})},getAllValues:function(){var e=this;return Object.keys(this.options).map((function(t){return Object.keys(e.options[t])})).flat()},getOptionIndex:function(e,t){for(var n=0,o=0;oCookie Policy.')}},necessary_cookies:{title:"Strictly Necessary Cookies",description:"These cookies are essential for the proper functioning of our website and don't store any user-identifiable data. Without these cookies, the website would not work properly. This option cannot be disabled."},analytics:{title:"Performance and Analytics Cookies",description:"These cookies collect information about how you use the website, which pages you visited and which links you clicked on. All of the data is anonymized and cannot be used to identify you.",analytics_description:"This cookie is installed by Google Analytics and used for the site’s analytics report. This information is stored anonymously and assigned a random number to identify unique visitors.",session_description:"This cookie is installed by Google Analytics for session management."},footer:{title:"More Information",description:function(e){return'For any queries in relation to our policy on cookies and your choices, please contact us.')}}}}}},cookieConsent:null,disableOutsideClick:function(){return this.options.disableOutsideClick=!0,this},overlayCrossButton:function(){return this.options.overlayCrossButton=!0,this},withtrackingAnalytics:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return this.options.trackingAnalytics={key:e,domain:t},this},withLocale:function(e){return this.options.locale=e,this},withLang:function(e){return this.options.lang=e,this},showSettings:function(){this.cookieConsent.showSettings()},init:function(e){var t,n,o=this,r=e.appName,i=e.domain,a=e.contactUrl;this.cookieConsent=initCookieConsent(null,this.options),this.options.trackingAnalytics&&(t=function(){var e=document.createElement("script");function t(){dataLayer.push(arguments)}e.id="google_analytics_script",e.type="text/javascript",e.src="https://www.googletagmanager.com/gtag/js?id=".concat(o.options.trackingAnalytics.key),document.body.append(e),window.dataLayer=window.dataLayer||[],t("js",new Date),t("config",o.options.trackingAnalytics.key)},n=function(){document.getElementById("google_analytics_script").remove();var e=document.cookie.split(";").filter((function(e){return e.trim().startsWith("_ga")})).map((function(e){return e.split("=")[0]})),t=o.options.trackingAnalytics.domain||document.domain;o.cookieConsent.eraseCookies(e,"/",t),window["ga-disable-".concat(o.options.trackingAnalytics.key)]=!0});var s={current_lang:this.options.locale,languages:{en:{consent_modal:{title:this.options.lang.consentModal.title,description:this.options.lang.consentModal.description,primary_btn:{text:this.options.lang.consentModal.primaryBtn.text,role:"accept_all"},secondary_btn:{text:this.options.lang.consentModal.secondaryBtn.text,role:"accept_necessary"}},settings_modal:{title:this.options.lang.settingsModal.title,save_settings_btn:this.options.lang.settingsModal.save_settings_btn,accept_all_btn:this.options.lang.settingsModal.accept_all_btn,reject_all_btn:this.options.lang.settingsModal.reject_all_btn,close_btn_label:this.options.lang.settingsModal.close_btn_label,cookie_table_headers:[{col1:this.options.lang.settingsModal.cookie_table_headers.name},{col2:this.options.lang.settingsModal.cookie_table_headers.domain},{col3:this.options.lang.settingsModal.cookie_table_headers.description}],blocks:[{title:this.options.lang.settingsModal.blocks.header.title,description:this.options.lang.settingsModal.blocks.header.description(r)},{title:this.options.lang.settingsModal.blocks.necessary_cookies.title,description:this.options.lang.settingsModal.blocks.necessary_cookies.description,toggle:{value:"necessary",enabled:!0,readonly:!0}},{title:this.options.lang.settingsModal.blocks.analytics.title,description:this.options.lang.settingsModal.blocks.analytics.description,toggle:{value:"analytics",enabled:!1,readonly:!1},cookie_table:[{col1:"^_ga",col2:i,col3:this.options.lang.settingsModal.blocks.analytics.analytics_description},{col1:"_ga_".concat(this.options.trackingAnalytics.key),col2:i,col3:this.options.lang.settingsModal.blocks.analytics.session_description}]},{title:this.options.lang.settingsModal.blocks.footer.title,description:this.options.lang.settingsModal.blocks.footer.description(a)}]}}},gui_options:{consent_modal:{layout:"cloud",position:"bottom center",transition:"slide"},settings_modal:{layout:"box",transition:"slide"}}};this.options.trackingAnalytics&&(s.onAccept=function(e){e.categories.includes("analytics")&&t()},s.onChange=function(e){e.categories.includes("analytics")?t():n()}),this.cookieConsent.run(s);var c=document.getElementById("c-txt");c&&c.insertAdjacentHTML("beforeend",' ')}};n(250),n(202);window.Alpine=o.Z,window.Dropdown=Vn,window.Modal=Fo,window.Navbar=Uo,window.Slider=zo,window.Pagination=Yo,window.RichSelect=Jo,window.Slider=zo,window.FileUpload=er(),window.CookieBanner=tr,o.Z.start()},859:()=>{window.uploadPhoto=function(e){return{url:e.url,onUpload:e.onUpload,upload:function(e){var t=this;if(e.target.files.length){var n=new FormData;n.append("logo",e.target.files[0]),fetch(this.url,{method:"POST",body:n}).then((function(){return t.onUpload()}))}},select:function(){document.getElementById("photo").click()}}}},471:()=>{function e(e,n){var o="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!o){if(Array.isArray(e)||(o=function(e,n){if(!e)return;if("string"==typeof e)return t(e,n);var o=Object.prototype.toString.call(e).slice(8,-1);"Object"===o&&e.constructor&&(o=e.constructor.name);if("Map"===o||"Set"===o)return Array.from(e);if("Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o))return t(e,n)}(e))||n&&e&&"number"==typeof e.length){o&&(e=o);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,c=!1;return{s:function(){o=o.call(e)},n:function(){var e=o.next();return s=e.done,e},e:function(e){c=!0,a=e},f:function(){try{s||null==o.return||o.return()}finally{if(c)throw a}}}}function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);ndocument.body.clientHeight&&(i.style="display: none; margin-top: -"+(a-document.body.clientHeight+20)+"px")}}}}catch(e){n.e(e)}finally{n.f()}}))},250:()=>{function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function t(t){for(var o=1;o0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){};return t({selected:e,select:function(e){this.selected=e,this.$refs[e].focus(),this.onSelected(e)},keyboard:function(e){var t=e.target.closest("[role=tablist]").querySelectorAll("[role=tab]"),n=Array.prototype.indexOf.call(t,e.currentTarget),o=37===e.keyCode?n-1:39===e.keyCode?n+1:40===e.keyCode?"down":null;null!==o&&("down"===o?this.select(e.currentTarget.id.replace("tab-","")):t[o]&&this.select(t[o].id.replace("tab-","")))},onSelected:o},n)}},607:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var o=n(645),r=n.n(o)()((function(e){return e[1]}));r.push([e.id,'.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{background-color:#333;border-radius:4px;color:#fff;font-size:14px;line-height:1.4;outline:0;position:relative;transition-property:transform,visibility,opacity;white-space:normal}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{border-top-color:initial;border-width:8px 8px 0;bottom:-7px;left:0;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:initial;border-width:0 8px 8px;left:0;top:-7px;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-left-color:initial;border-width:8px 0 8px 8px;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{border-right-color:initial;border-width:8px 8px 8px 0;left:-7px;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{color:#333;height:16px;width:16px}.tippy-arrow:before{border-color:transparent;border-style:solid;content:"";position:absolute}.tippy-content{padding:5px 9px;position:relative;z-index:1}',""]);const i=r},645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=e(t);return t[2]?"@media ".concat(t[2]," {").concat(n,"}"):n})).join("")},t.i=function(e,n,o){"string"==typeof e&&(e=[[null,e,""]]);var r={};if(o)for(var i=0;i{},379:(e,t,n)=>{"use strict";var o,r=function(){return void 0===o&&(o=Boolean(window&&document&&document.all&&!window.atob)),o},i=function(){var e={};return function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}e[t]=n}return e[t]}}(),a=[];function s(e){for(var t=-1,n=0;n{var t=t=>e(e.s=t);e.O(0,[170,898],(()=>(t(368),t(81))));e.O()}]); \ No newline at end of file diff --git a/public/js/app.js.LICENSE b/public/js/app.js.LICENSE new file mode 100644 index 0000000..e56a96c --- /dev/null +++ b/public/js/app.js.LICENSE @@ -0,0 +1,5 @@ +/*! + * Vue.js v2.6.11 + * (c) 2014-2019 Evan You + * Released under the MIT License. + */ diff --git a/public/js/app.js.LICENSE.txt b/public/js/app.js.LICENSE.txt new file mode 100644 index 0000000..0812e4a --- /dev/null +++ b/public/js/app.js.LICENSE.txt @@ -0,0 +1,4 @@ +/*! +* focus-trap 6.9.4 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/ diff --git a/public/js/clipboard.js b/public/js/clipboard.js new file mode 100644 index 0000000..418ea61 --- /dev/null +++ b/public/js/clipboard.js @@ -0,0 +1 @@ +(self.webpackChunk=self.webpackChunk||[]).push([[934],{619:()=>{window.clipboard=function(){return{copying:!1,notSupported:!1,copy:function(e){var t=this;this.copying=!0;var n=window.navigator.clipboard;n&&window.isSecureContext?n.writeText(e).then((function(){return t.copying=!1}),(function(){t.copying=!1,console.error("Failed to copy contents to the clipboard.")})):(console.warn("Using fallback due to lack of navigator support or HTTPS in this browser"),this.copyUsingExec(e))},copyUsingExec:function(e){var t=this,n=document.createElement("textarea");if(n.value=e,n.setAttribute("readonly",""),n.style.cssText="position:absolute;top:0;left:0;z-index:-9999;opacity:0;fontSize:12pt;",this.$root.append(n),navigator.userAgent.match(/ipad|iphone/i)){var o=n.contentEditable,i=n.readOnly;n.contentEditable="true",n.readOnly=!1;var c=document.createRange();c.selectNodeContents(n);var a=window.getSelection();a&&(a.removeAllRanges(),a.addRange(c)),n.setSelectionRange(0,999999),n.contentEditable=o,n.readOnly=i}else n.select(),n.focus();this.copying=!0,setTimeout((function(){return t.copying=!1}),1200),document.execCommand("copy"),n.remove()},copyFromInput:function(e){var t=document.querySelector(e);this.copy(t.value)}}}}},e=>{var t;t=619,e(e.s=t)}]); \ No newline at end of file diff --git a/public/js/cookie-consent.js b/public/js/cookie-consent.js new file mode 100644 index 0000000..0c6069c --- /dev/null +++ b/public/js/cookie-consent.js @@ -0,0 +1,2 @@ +/*! For license information please see cookie-consent.js.LICENSE.txt */ +(self.webpackChunk=self.webpackChunk||[]).push([[252],{557:()=>{function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}!function(){"use strict";var t="initCookieConsent";"function"!=typeof window[t]&&(window[t]=function(t){var n,o,i,a,c,r,s,l,d,u,p,f,g,h,v,m,_,b,y,k,C,A,w,x,S,N,T,L,O,E,j=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},M=!1,H={mode:"opt-in",current_lang:"en",auto_language:null,autorun:!0,page_scripts:!0,hide_from_bots:!0,cookie_name:"cc_cookie",cookie_expiration:365,cookie_domain:window.location.hostname,avoid_explicit_domain:!0,cookie_path:"/",cookie_same_site:"Lax",use_rfc_cookie:!0,autoclear_cookies:!0,revision:0,script_selector:"data-cookiecategory"},I={},D={},J=null,G=!1,P=!1,U=!1,q=!1,F=!1,R=!1,z=!0,B="",K=[],V=!1,$=[],Q=[],W=[],X=!1,Y=[],Z=[],ee=[],te=[],ne=[],oe=document.documentElement,ie=function(e){ge("CookieConsent [CONFIG]: received_config_settings ",n=e),"number"==typeof n.cookie_expiration&&(H.cookie_expiration=n.cookie_expiration),"number"==typeof n.cookie_necessary_only_expiration&&(H.cookie_necessary_only_expiration=n.cookie_necessary_only_expiration),"boolean"==typeof n.autorun&&(H.autorun=n.autorun),"string"==typeof n.cookie_domain&&(H.cookie_domain=n.cookie_domain),"boolean"==typeof n.avoid_explicit_domain&&(H.avoid_explicit_domain=n.avoid_explicit_domain),"string"==typeof n.cookie_same_site&&(H.cookie_same_site=n.cookie_same_site),"string"==typeof n.cookie_path&&(H.cookie_path=n.cookie_path),"string"==typeof n.cookie_name&&(H.cookie_name=n.cookie_name),"function"==typeof n.onAccept&&(c=n.onAccept),"function"==typeof n.onFirstAction&&(s=n.onFirstAction),"function"==typeof n.onChange&&(r=n.onChange),"opt-out"===n.mode&&(H.mode="opt-out"),"number"==typeof n.revision&&(n.revision>-1&&(H.revision=n.revision),R=!0),"boolean"==typeof n.autoclear_cookies&&(H.autoclear_cookies=n.autoclear_cookies),!0===n.use_rfc_cookie&&(H.use_rfc_cookie=!0),!0===n.hide_from_bots&&(X=navigator&&(navigator.userAgent&&/bot|crawl|spider|slurp|teoma/i.test(navigator.userAgent)||navigator.webdriver)),H.page_scripts=!0===n.page_scripts,"browser"===n.auto_language||!0===n.auto_language?H.auto_language="browser":"document"===n.auto_language&&(H.auto_language="document"),ge("CookieConsent [LANG]: auto_language strategy is '"+H.auto_language+"'"),H.current_lang=ve(n.languages,n.current_lang)},ae=function(e){for(var t="accept-",n=r("c-settings"),o=r(t+"all"),i=r(t+"necessary"),a=r(t+"custom"),c=0;c0?Object.prototype.hasOwnProperty.call(t,H.current_lang)?H.current_lang:Te(t)[0]:void 0},re=function(){var e=["[href]","button","input","details",'[tabindex="0"]'];function t(t,n){var o=!1,i=!1;try{for(var a,c=t.querySelectorAll(e.join(':not([tabindex="-1"]), ')),r=c.length,s=0;s-1?(U.checked=!0,!N&&ee.push(!0)):!N&&ee.push(!1):g.enabled?(U.checked=!0,!N&&ee.push(!0),g.enabled&&!N&&W.push(B)):!N&&ee.push(!1),!N&&te.push(B),g.readonly?(U.disabled=!0,Le(q,"c-ro"),!N&&ne.push(!0)):!N&&ne.push(!1),Le(b,"b-acc"),Le(M,"b-bn"),Le(_,"b-ex"),b.id=H,b.setAttribute("aria-hidden","true"),P.appendChild(U),P.appendChild(q),P.appendChild(F),M.appendChild(P),m&&function(e,t,n){Ne(J,"click",(function(){Ee(t,"act")?(Oe(t,"act"),n.setAttribute("aria-expanded","false"),e.setAttribute("aria-hidden","true")):(Le(t,"act"),n.setAttribute("aria-expanded","true"),e.setAttribute("aria-hidden","false"))}),!1)}(b,_,J)}else if(u){var K=he("div");K.className="b-tl",K.setAttribute("role","heading"),K.setAttribute("aria-level","3"),K.insertAdjacentHTML("beforeend",u),M.appendChild(K)}if(u&&_.appendChild(M),p&&b.appendChild(y),!v&&void 0!==h){for(var V=document.createDocumentFragment(),$=0;$
\x3c!--\x3e
\x3c!---1;if(!ee[++n]&&Object.prototype.hasOwnProperty.call(l,"cookie_table")&&(e||d)){var u=l.cookie_table,p=Te(i[0])[0],f=u.length;"on_disable"===l.toggle.reload&&d&&(V=!0);for(var g=0;g-1&&v.push(o[C])}ge("CookieConsent [AUTOCLEAR]: search cookie: '"+m+"', found:",v),v.length>0&&(Se(v,y,c),"on_clear"===l.toggle.reload&&(V=!0))}}}}},pe=function(e){K=[];var t=document.querySelectorAll(".c-tgl")||[];if(t.length>0)for(var n=0;n0&&ue(),D={categories:e,revision:H.revision,data:J,rfc_cookie:H.use_rfc_cookie},(!G||K.length>0||!z)&&(z=!0,l=Ae(Ce()),we(H.cookie_name,JSON.stringify(D)),ye()),(G||(H.autoclear_cookies&&ue(!0),"function"==typeof s&&s(I.getUserPreferences(),D),"function"==typeof c&&c(D),G=!0,"opt-in"!==H.mode))&&("function"==typeof r&&K.length>0&&r(D,K),V&&window.location.reload())},fe=function(e,t){return e.indexOf(t)},ge=function(e,t,n){M&&(n?console.error(e,t||""):console.log(e,void 0!==t?t:" "))},he=function(e){var t=document.createElement(e);return"button"===e&&t.setAttribute("type",e),t},ve=function(e,t){return"browser"===H.auto_language?ce(me(),e):"document"===H.auto_language?ce(document.documentElement.lang,e):"string"==typeof t?H.current_lang=ce(t,e):(ge("CookieConsent [LANG]: setting current_lang = '"+H.current_lang+"'"),H.current_lang)},me=function(){var e=navigator.language||navigator.browserLanguage;return e.length>2&&(e=e[0]+e[1]),ge("CookieConsent [LANG]: detected_browser_lang = '"+e+"'"),e.toLowerCase()},_e=function(){var e=!1,t=!1;Ne(document,"keydown",(function(n){"Tab"===(n=n||window.event).key&&(o&&(n.shiftKey?document.activeElement===o[0]&&(o[1].focus(),n.preventDefault()):document.activeElement===o[1]&&(o[0].focus(),n.preventDefault()),t||F||(t=!0,!e&&n.preventDefault(),n.shiftKey?o[3]?o[2]?o[2].focus():o[0].focus():o[1].focus():o[3]?o[3].focus():o[0].focus())),!t&&(e=!0))})),document.contains&&!j.disableOutsideClick&&Ne(p,"click",(function(e){e=e||window.event,q?C.contains(e.target)?F=!0:(I.hideSettings(0),F=!1):U&&g.contains(e.target)&&(F=!0)}),!0)},be=function(t,n){if("object"===e(t)){var o=t.consent_modal,i=t.settings_modal;P&&o&&a(g,["box","bar","cloud"],["top","middle","bottom"],["zoom","slide"],o.layout,o.position,o.transition),!n&&i&&a(k,["bar"],["left","right"],["zoom","slide"],i.layout,i.position,i.transition)}function a(e,t,n,o,i,a,c){if(a=a&&a.split(" ")||[],fe(t,i)>-1&&(Le(e,i),("bar"!==i||"middle"!==a[0])&&fe(n,a[0])>-1))for(var r=0;r-1&&Le(e,c)}};I.allowedCategory=function(e){if(G||"opt-in"===H.mode)var t=JSON.parse(xe(H.cookie_name,"one",!0)||"{}").categories||[];else t=W;return fe(t,e)>-1},I.run=function(e){if(document.getElementById("cc_div"))ge("CookieConsent [NOTICE]: cookie consent already attached to body!");else{if(ie(e),X)return;if(void 0!==(D=JSON.parse(xe(H.cookie_name,"one",!0)||"{}")).level&&(D.categories=D.level,delete D.level,Se([H.cookie_name],"/",[H.cookie_domain,"."+H.cookie_domain]),we(H.cookie_name,JSON.stringify(D))),G=void 0!==D.categories,J=void 0!==D.data?D.data:null,z=!("number"==typeof e.revision&&G&&e.revision>-1&&D.revision!==H.revision),P=!G||!z,de(),re(),be(e.gui_options),ae(),H.autorun&&P&&I.show(e.delay||0),setTimeout((function(){Le(p,"c--anim")}),30),setTimeout((function(){_e()}),100),G&&z){var t="boolean"==typeof D.rfc_cookie;(!t||t&&D.rfc_cookie!==H.use_rfc_cookie)&&(D.rfc_cookie=H.use_rfc_cookie,we(H.cookie_name,JSON.stringify(D))),l=Ae(Ce()),ye(),"function"==typeof c&&c(D)}else"opt-out"===H.mode&&(ge("CookieConsent [CONFIG] mode='"+H.mode+"', default enabled categories:",W),ye(W))}},I.showSettings=function(e){setTimeout((function(){Le(oe,"show--settings"),k.setAttribute("aria-hidden","false"),x.removeAttribute("style"),q=!0,setTimeout((function(){U?u=document.activeElement:d=document.activeElement,0!==Z.length&&(Z[3]?Z[3].focus():Z[0].focus(),o=Z)}),200),ge("CookieConsent [SETTINGS]: show settings_modal")}),e>0?e:0)};var ye=function(e){if(H.page_scripts){var t=document.querySelectorAll("script["+H.script_selector+"]"),n=e||D.categories||[];!function e(t,o){if(o-1){i.type="text/javascript",i.removeAttribute(H.script_selector);var c=i.getAttribute("data-src");c&&i.removeAttribute("data-src");var r=he("script");if(r.textContent=i.innerHTML,function(e,t){for(var n=t.attributes,o=n.length,i=0;i0)for(var a=0;a0?e:t?30:0)},I.hide=function(){P&&(Oe(oe,"show--consent"),g.setAttribute("aria-hidden","true"),U=!1,setTimeout((function(){d.focus(),o=null}),200),ge("CookieConsent [MODAL]: hide"))},I.hideSettings=function(){Oe(oe,"show--settings"),q=!1,k.setAttribute("aria-hidden","true"),x.style="display: none",setTimeout((function(){U?(u&&u.focus(),o=Y):(d&&d.focus(),o=null),F=!1}),200),ge("CookieConsent [SETTINGS]: hide settings_modal")},I.accept=function(t,n){var o=t||void 0,i=n||[],a=[];if(o)if("object"===e(o)&&"number"==typeof o.length)for(var c=0;c=1)for(c=0;c0)for(var c=0;c-1;a&&c&&(i+=" Domain="+H.cookie_domain+";"),"https:"===window.location.protocol&&(i+=" Secure;"),document.cookie=i,ge("CookieConsent [SET_COOKIE]: cookie "+e+"='"+t+"' was set! Expires after "+n+" days")},xe=function(e,t,n){var o;if("one"===t){if((o=(o=document.cookie.match("(^|;)\\s*"+e+"\\s*=\\s*([^;]+)"))?n?o.pop():e:"")&&e===H.cookie_name){try{o=JSON.parse(o)}catch(e){try{o=JSON.parse(decodeURIComponent(o))}catch(e){o={}}}o=JSON.stringify(o)}}else if("all"===t){var i=document.cookie.split(/;\s*/);o=[];for(var a=0;a-1?"; domain="+n[a]:"")+"; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";ge("CookieConsent [AUTOCLEAR]: deleting cookie: '"+e[i]+"' path: '"+o+"' domain:",n)}};I.validCookie=function(e){return""!==xe(e,"one",!0)};var Ne=function(e,t,n,o){var i=!0===o;e.addEventListener?i?e.addEventListener(t,n,{passive:!0}):e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)},Te=function(t){if("object"===e(t)){var n=[],o=0;for(var i in t)n[o++]=i;return n}},Le=function(e,t){e.classList?e.classList.add(t):Ee(e,t)||(e.className+=" "+t)},Oe=function(e,t){e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp("(\\s|^)"+t+"(\\s|$)")," ")},Ee=function(e,t){return e.classList?e.classList.contains(t):!!e.className.match(new RegExp("(\\s|^)"+t+"(\\s|$)"))};return I})}()}},e=>{var t;t=557,e(e.s=t)}]); \ No newline at end of file diff --git a/public/js/cookie-consent.js.LICENSE.txt b/public/js/cookie-consent.js.LICENSE.txt new file mode 100644 index 0000000..6747992 --- /dev/null +++ b/public/js/cookie-consent.js.LICENSE.txt @@ -0,0 +1,8 @@ +/*! + * CookieConsent v3.0.0-beta.1 + * https://www.github.com/orestbida/cookieconsent + * Author Orest Bida + * Released under the MIT License + * + * This is a copy of https://www.github.com/orestbida/cookieconsent with minor adjustments for ARK.io-related projects + */ diff --git a/public/js/crop-image.js b/public/js/crop-image.js new file mode 100644 index 0000000..0409ccb --- /dev/null +++ b/public/js/crop-image.js @@ -0,0 +1,2 @@ +/*! For license information please see crop-image.js.LICENSE.txt */ +(self.webpackChunk=self.webpackChunk||[]).push([[765],{961:(t,e,i)=>{"use strict";var a=i(379),n=i.n(a),r=i(722),o={insert:"head",singleton:!1};n()(r.Z,o);r.Z.locals;var h=i(129),s=i.n(h),c=i(144),l=function(t){throw new Error(t||"Received invalid response")};function p(t){return function(t){if(Array.isArray(t))return d(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return d(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);"Object"===i&&t.constructor&&(i=t.constructor.name);if("Map"===i||"Set"===i)return Array.from(t);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return d(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,a=new Array(e);i0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:200,o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:200,h=arguments.length>7&&void 0!==arguments[7]?arguments[7]:1e3,d=arguments.length>8&&void 0!==arguments[8]?arguments[8]:1e3,g=arguments.length>9&&void 0!==arguments[9]?arguments[9]:900,m=arguments.length>10&&void 0!==arguments[10]?arguments[10]:900,f=arguments.length>11&&void 0!==arguments[11]?arguments[11]:2,v=arguments.length>12&&void 0!==arguments[12]?arguments[12]:"#fff",w=!(arguments.length>13&&void 0!==arguments[13])||arguments[13],b=arguments.length>14&&void 0!==arguments[14]?arguments[14]:"high",y=arguments.length>15&&void 0!==arguments[15]?arguments[15]:"/cropper/upload-image";return{model:e,cropper:null,isUploading:!1,isPreparingImage:!0,isCropping:!1,uploadEl:null,cropEl:null,modalCancelButton:null,modalSaveButton:null,cropElementIsReady:function(){var t=this;return new Promise((function(e,i){var a=function(){var i=setInterval((function(){t.cropEl.parentNode.clientHeight?(clearInterval(i),e()):u("tries")}),50)};t.cropEl.complete?a():t.cropEl.onload=function(){return a()}}))},init:function(){var e=this;this.uploadEl=document.getElementById(i),Livewire.on("discardCroppedImage",(function(){Livewire.emit("closeModal",n),e.discardImage()})),Livewire.on("saveCroppedImage",(function(){Livewire.emit("closeModal",n),e.saveCroppedImage(),e.discardImage()})),Livewire.on("cropModalShown",(function(i){"crop-modal-".concat(i)===n&&e.cropElementIsReady().then((function(){e.isPreparingImage=!1,e.$nextTick((function(){e.cropper=new(s())(e.cropEl,t)}))}))})),Livewire.on("cropModalBeforeHide",(function(t){"crop-modal-".concat(t)===n&&e.destroyCropper()}))},destroyCropper:function(){this.cropper&&(this.cropper.destroy(),this.cropper=null)},select:function(){this.uploadEl.click()},validateImage:function(){var t=this;this.uploadEl.files.length&&(0,c.ck)(this.uploadEl.files[0],[{rule:"minWidth",value:r},{rule:"maxWidth",value:h},{rule:"minHeight",value:o},{rule:"maxHeight",value:d},{rule:"maxFileSize",value:f}]).then((function(){t.loadCropper()})).catch((function(e){(0,c.HN)(t.uploadEl),Object.values(e.getAll()).forEach((function(t){p(t).forEach((function(t){var e=t.value;return Livewire.emit("toastMessage",[e,"danger"])}))}))}))},loadCropper:function(){var t=this;if(this.uploadEl.files.length){this.isPreparingImage=!0;var e=new FileReader;e.onload=function(e){e.target.result&&(t.cropEl=document.getElementById(a),t.cropEl.src=e.target.result)},e.readAsDataURL(this.uploadEl.files[0]),this.openCropModal()}},saveCroppedImage:function(){var t=this;if(this.cropper){var e=this.cropper.getCroppedCanvas({width:g,height:m,fillColor:v,imageSmoothingEnabled:w,imageSmoothingQuality:b});e&&e.toBlob((function(e){(0,c.Ix)(e,y,(0,c._V)()).then((function(e){e.url||l(),t.model=e.url}))}))}},discardImage:function(){this.destroyCropper(),(0,c.HN)(this.uploadEl)},openCropModal:function(){Livewire.emit("openModal",n)}}}},144:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";__webpack_require__.d(__webpack_exports__,{Ix:()=>uploadImage,ck:()=>imageValidator,_V:()=>getCsrfToken,HN:()=>resetUploadInput});var _utils_error_bag__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(981),uploadImage=function(t,e,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"image",n=new FormData;return n.append(a,t),fetch(e,{method:"POST",body:n,headers:{"X-Requested-With":"XMLHttpRequest","X-CSRF-TOKEN":i}}).then((function(t){var e=t.status;if(200===e)return t.json();if(419===e)throw new Error("Session expired. You will need to refresh the browser to continue uploading images.");t.text().then((function(t){throw new Error(t)}))})).catch((function(t){throw new Error(t)}))},imageValidator=function imageValidator(inputFile){var rules=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],errorBag=new _utils_error_bag__WEBPACK_IMPORTED_MODULE_0__.Z(inputFile.name),image=new Image,ruleset=["minWidth","maxWidth","minHeight","maxHeight","minFileSize","maxFileSize"],minWidth=function(t,e){t.widthe&&errorBag.add(getCallerName(),"The image should be no bigger than ".concat(e,"x").concat(e,"px"))},maxHeight=function(t,e){t.height>e&&errorBag.add(getCallerName(),"The image should be no bigger than ".concat(e,"x").concat(e,"px"))},minFileSize=function(t,e){bytesToMegabytes(t.size)e&&errorBag.add(getCallerName(),"The image should be no bigger than ".concat(e,"MB"))};return image.src=URL.createObjectURL(inputFile),image.size=inputFile.size,new Promise((function(resolve,reject){image.onload=function(e){rules.forEach((function(item){item.hasOwnProperty("rule")&&ruleset.includes(item.rule)&&eval(item.rule)(e.target,parseInt(item.value))})),errorBag.hasErrors()&&reject(errorBag),resolve()}}))},getCallerName=function(){return(new Error).stack.split("\n")[2].replace(/^\s+at\s+(.+?)\s.+/g,"$1")},bytesToMegabytes=function(t){return parseFloat("".concat(parseInt(t)/1e3/1e3)).toFixed(2)},getCsrfToken=function(){return document.querySelector("meta[name=csrf-token]").content},resetUploadInput=function(t){t.value="",t.type="",t.type="file"}},981:(t,e,i)=>{"use strict";function a(t){return function(t){if(Array.isArray(t))return n(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return n(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);"Object"===i&&t.constructor&&(i=t.constructor.name);if("Map"===i||"Set"===i)return Array.from(t);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return n(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,a=new Array(e);ih});var h=function(){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;r(this,t),this.defaultBagName="default",this.collection={},e||(this.defaultBagName=e)}var e,i,n;return e=t,i=[{key:"add",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.defaultBagName;t||e?(this.collection.hasOwnProperty(i)||(this.collection[i]=[]),this.addItem(t,e,i)):this.collection[i]=[]}},{key:"reset",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.defaultBagName;this.add(t)}},{key:"get",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.defaultBagName;return t?this.collection[e].find((function(e){return e.key===t})):this.getBag(e)}},{key:"hasErrors",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.defaultBagName;return this.hasBag(t)&&this.getBag(t).length>0}},{key:"remove",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.defaultBagName;if(t){var i=this.collection[e];i.splice(i.findIndex((function(e){return e.key===t})),1)}else delete this.collection[e]}},{key:"getAll",value:function(){return this.collection}},{key:"resetAll",value:function(){this.collection={}}},{key:"unify",value:function(){var e={};return Object.entries(this.collection).forEach((function(t){a(t).forEach((function(i){for(var a,n=0,r=i.map((function(t){return Object.assign({},t)})),o=[];n-1?r.splice(n,1):o.push(a),n++;e[t[0]]=r}))})),this.collection=e,t}},{key:"hasBag",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.defaultBagName;return this.collection.hasOwnProperty(t)}},{key:"getBag",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.defaultBagName;return this.collection[t]}},{key:"addItem",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.defaultBagName;this.collection[i].push(this.errorItem(t,e))}},{key:"errorItem",value:function(t,e){return{key:t,value:e}}}],i&&o(e.prototype,i),n&&o(e,n),t}()},129:function(t){t.exports=function(){"use strict";function t(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function e(e){for(var i=1;it.length)&&(e=t.length);for(var i=0,a=new Array(e);i
',dt=Number.isNaN||g.isNaN;function ut(t){return"number"==typeof t&&!dt(t)}var gt=function(t){return t>0&&t<1/0};function mt(t){return void 0===t}function ft(t){return"object"===i(t)&&null!==t}var vt=Object.prototype.hasOwnProperty;function wt(t){if(!ft(t))return!1;try{var e=t.constructor,i=e.prototype;return e&&i&&vt.call(i,"isPrototypeOf")}catch(t){return!1}}function bt(t){return"function"==typeof t}var yt=Array.prototype.slice;function xt(t){return Array.from?Array.from(t):yt.call(t)}function Mt(t,e){return t&&bt(e)&&(Array.isArray(t)||ut(t.length)?xt(t).forEach((function(i,a){e.call(t,i,a,t)})):ft(t)&&Object.keys(t).forEach((function(i){e.call(t,t[i],i,t)}))),t}var Ct=Object.assign||function(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),a=1;a0&&i.forEach((function(e){ft(e)&&Object.keys(e).forEach((function(i){t[i]=e[i]}))})),t},kt=/\.\d*(?:0|9){12}\d*$/;function Bt(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1e11;return kt.test(t)?Math.round(t*e)/e:t}var Dt=/^width|height|left|top|marginLeft|marginTop$/;function Et(t,e){var i=t.style;Mt(e,(function(t,e){Dt.test(e)&&ut(t)&&(t="".concat(t,"px")),i[e]=t}))}function At(t,e){return t.classList?t.classList.contains(e):t.className.indexOf(e)>-1}function Tt(t,e){if(e)if(ut(t.length))Mt(t,(function(t){Tt(t,e)}));else if(t.classList)t.classList.add(e);else{var i=t.className.trim();i?i.indexOf(e)<0&&(t.className="".concat(i," ").concat(e)):t.className=e}}function Ot(t,e){e&&(ut(t.length)?Mt(t,(function(t){Ot(t,e)})):t.classList?t.classList.remove(e):t.className.indexOf(e)>=0&&(t.className=t.className.replace(e,"")))}function Nt(t,e,i){e&&(ut(t.length)?Mt(t,(function(t){Nt(t,e,i)})):i?Tt(t,e):Ot(t,e))}var Ht=/([a-z\d])([A-Z])/g;function St(t){return t.replace(Ht,"$1-$2").toLowerCase()}function It(t,e){return ft(t[e])?t[e]:t.dataset?t.dataset[e]:t.getAttribute("data-".concat(St(e)))}function zt(t,e,i){ft(i)?t[e]=i:t.dataset?t.dataset[e]=i:t.setAttribute("data-".concat(St(e)),i)}function Wt(t,e){if(ft(t[e]))try{delete t[e]}catch(i){t[e]=void 0}else if(t.dataset)try{delete t.dataset[e]}catch(i){t.dataset[e]=void 0}else t.removeAttribute("data-".concat(St(e)))}var Lt=/\s\s*/,Rt=function(){var t=!1;if(u){var e=!1,i=function(){},a=Object.defineProperty({},"once",{get:function(){return t=!0,e},set:function(t){e=t}});g.addEventListener("test",i,a),g.removeEventListener("test",i,a)}return t}();function jt(t,e,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},n=i;e.trim().split(Lt).forEach((function(e){if(!Rt){var r=t.listeners;r&&r[e]&&r[e][i]&&(n=r[e][i],delete r[e][i],0===Object.keys(r[e]).length&&delete r[e],0===Object.keys(r).length&&delete t.listeners)}t.removeEventListener(e,n,a)}))}function _t(t,e,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},n=i;e.trim().split(Lt).forEach((function(e){if(a.once&&!Rt){var r=t.listeners,o=void 0===r?{}:r;n=function(){delete o[e][i],t.removeEventListener(e,n,a);for(var r=arguments.length,h=new Array(r),s=0;sMath.abs(a)&&(a=s)}))})),a}function Vt(t,i){var a=t.pageX,n=t.pageY,r={endX:a,endY:n};return i?r:e({startX:a,startY:n},r)}function $t(t){var e=0,i=0,a=0;return Mt(t,(function(t){var n=t.startX,r=t.startY;e+=n,i+=r,a+=1})),{pageX:e/=a,pageY:i/=a}}function Kt(t){var e=t.aspectRatio,i=t.height,a=t.width,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"contain",r=gt(a),o=gt(i);if(r&&o){var h=i*e;"contain"===n&&h>a||"cover"===n&&h90?{width:s,height:h}:{width:h,height:s}}function Jt(t,e,i,a){var n=e.aspectRatio,r=e.naturalWidth,o=e.naturalHeight,s=e.rotate,c=void 0===s?0:s,l=e.scaleX,p=void 0===l?1:l,d=e.scaleY,u=void 0===d?1:d,g=i.aspectRatio,m=i.naturalWidth,f=i.naturalHeight,v=a.fillColor,w=void 0===v?"transparent":v,b=a.imageSmoothingEnabled,y=void 0===b||b,x=a.imageSmoothingQuality,M=void 0===x?"low":x,C=a.maxWidth,k=void 0===C?1/0:C,B=a.maxHeight,D=void 0===B?1/0:B,E=a.minWidth,A=void 0===E?0:E,T=a.minHeight,O=void 0===T?0:T,N=document.createElement("canvas"),H=N.getContext("2d"),S=Kt({aspectRatio:g,width:k,height:D}),I=Kt({aspectRatio:g,width:A,height:O},"cover"),z=Math.min(S.width,Math.max(I.width,m)),W=Math.min(S.height,Math.max(I.height,f)),L=Kt({aspectRatio:n,width:k,height:D}),R=Kt({aspectRatio:n,width:A,height:O},"cover"),j=Math.min(L.width,Math.max(R.width,r)),_=Math.min(L.height,Math.max(R.height,o)),X=[-j/2,-_/2,j,_];return N.width=Bt(z),N.height=Bt(W),H.fillStyle=w,H.fillRect(0,0,z,W),H.save(),H.translate(z/2,W/2),H.rotate(c*Math.PI/180),H.scale(p,u),H.imageSmoothingEnabled=y,H.imageSmoothingQuality=M,H.drawImage.apply(H,[t].concat(h(X.map((function(t){return Math.floor(Bt(t))}))))),H.restore(),N}var te=String.fromCharCode;function ee(t,e,i){var a="";i+=e;for(var n=e;n0;)i.push(te.apply(null,xt(n.subarray(0,a)))),n=n.subarray(a);return"data:".concat(e,";base64,").concat(btoa(i.join("")))}function re(t){var e,i=new DataView(t);try{var a,n,r;if(255===i.getUint8(0)&&216===i.getUint8(1))for(var o=i.byteLength,h=2;h+1=8&&(r=s+l)}}}if(r){var p,d,u=i.getUint16(r,a);for(d=0;d=0?n:st),height:Math.max(i.offsetHeight,r>=0?r:ct)};this.containerData=o,Et(a,{width:o.width,height:o.height}),Tt(t,H),Ot(a,H)},initCanvas:function(){var t=this.containerData,e=this.imageData,i=this.options.viewMode,a=Math.abs(e.rotate)%180==90,n=a?e.naturalHeight:e.naturalWidth,r=a?e.naturalWidth:e.naturalHeight,o=n/r,h=t.width,s=t.height;t.height*o>t.width?3===i?h=t.height*o:s=t.width/o:3===i?s=t.width/o:h=t.height*o;var c={aspectRatio:o,naturalWidth:n,naturalHeight:r,width:h,height:s};this.canvasData=c,this.limited=1===i||2===i,this.limitCanvas(!0,!0),c.width=Math.min(Math.max(c.width,c.minWidth),c.maxWidth),c.height=Math.min(Math.max(c.height,c.minHeight),c.maxHeight),c.left=(t.width-c.width)/2,c.top=(t.height-c.height)/2,c.oldLeft=c.left,c.oldTop=c.top,this.initialCanvasData=Ct({},c)},limitCanvas:function(t,e){var i=this.options,a=this.containerData,n=this.canvasData,r=this.cropBoxData,o=i.viewMode,h=n.aspectRatio,s=this.cropped&&r;if(t){var c=Number(i.minCanvasWidth)||0,l=Number(i.minCanvasHeight)||0;o>1?(c=Math.max(c,a.width),l=Math.max(l,a.height),3===o&&(l*h>c?c=l*h:l=c/h)):o>0&&(c?c=Math.max(c,s?r.width:0):l?l=Math.max(l,s?r.height:0):s&&(c=r.width,(l=r.height)*h>c?c=l*h:l=c/h));var p=Kt({aspectRatio:h,width:c,height:l});c=p.width,l=p.height,n.minWidth=c,n.minHeight=l,n.maxWidth=1/0,n.maxHeight=1/0}if(e)if(o>(s?0:1)){var d=a.width-n.width,u=a.height-n.height;n.minLeft=Math.min(0,d),n.minTop=Math.min(0,u),n.maxLeft=Math.max(0,d),n.maxTop=Math.max(0,u),s&&this.limited&&(n.minLeft=Math.min(r.left,r.left+(r.width-n.width)),n.minTop=Math.min(r.top,r.top+(r.height-n.height)),n.maxLeft=r.left,n.maxTop=r.top,2===o&&(n.width>=a.width&&(n.minLeft=Math.min(0,d),n.maxLeft=Math.max(0,d)),n.height>=a.height&&(n.minTop=Math.min(0,u),n.maxTop=Math.max(0,u))))}else n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height},renderCanvas:function(t,e){var i=this.canvasData,a=this.imageData;if(e){var n=Gt({width:a.naturalWidth*Math.abs(a.scaleX||1),height:a.naturalHeight*Math.abs(a.scaleY||1),degree:a.rotate||0}),r=n.width,o=n.height,h=i.width*(r/i.naturalWidth),s=i.height*(o/i.naturalHeight);i.left-=(h-i.width)/2,i.top-=(s-i.height)/2,i.width=h,i.height=s,i.aspectRatio=r/o,i.naturalWidth=r,i.naturalHeight=o,this.limitCanvas(!0,!1)}(i.width>i.maxWidth||i.widthi.maxHeight||i.heighte.width?n.height=n.width/i:n.width=n.height*i),this.cropBoxData=n,this.limitCropBox(!0,!0),n.width=Math.min(Math.max(n.width,n.minWidth),n.maxWidth),n.height=Math.min(Math.max(n.height,n.minHeight),n.maxHeight),n.width=Math.max(n.minWidth,n.width*a),n.height=Math.max(n.minHeight,n.height*a),n.left=e.left+(e.width-n.width)/2,n.top=e.top+(e.height-n.height)/2,n.oldLeft=n.left,n.oldTop=n.top,this.initialCropBoxData=Ct({},n)},limitCropBox:function(t,e){var i=this.options,a=this.containerData,n=this.canvasData,r=this.cropBoxData,o=this.limited,h=i.aspectRatio;if(t){var s=Number(i.minCropBoxWidth)||0,c=Number(i.minCropBoxHeight)||0,l=o?Math.min(a.width,n.width,n.width+n.left,a.width-n.left):a.width,p=o?Math.min(a.height,n.height,n.height+n.top,a.height-n.top):a.height;s=Math.min(s,a.width),c=Math.min(c,a.height),h&&(s&&c?c*h>s?c=s/h:s=c*h:s?c=s/h:c&&(s=c*h),p*h>l?p=l/h:l=p*h),r.minWidth=Math.min(s,l),r.minHeight=Math.min(c,p),r.maxWidth=l,r.maxHeight=p}e&&(o?(r.minLeft=Math.max(0,n.left),r.minTop=Math.max(0,n.top),r.maxLeft=Math.min(a.width,n.left+n.width)-r.width,r.maxTop=Math.min(a.height,n.top+n.height)-r.height):(r.minLeft=0,r.minTop=0,r.maxLeft=a.width-r.width,r.maxTop=a.height-r.height))},renderCropBox:function(){var t=this.options,e=this.containerData,i=this.cropBoxData;(i.width>i.maxWidth||i.widthi.maxHeight||i.height=e.width&&i.height>=e.height?y:w),Et(this.cropBox,Ct({width:i.width,height:i.height},Zt({translateX:i.left,translateY:i.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),Xt(this.element,Y,this.getData())}},se={initPreview:function(){var t=this.element,e=this.crossOrigin,i=this.options.preview,a=e?this.crossOriginUrl:this.url,n=t.alt||"The image to preview",r=document.createElement("img");if(e&&(r.crossOrigin=e),r.src=a,r.alt=n,this.viewBox.appendChild(r),this.viewBoxImage=r,i){var o=i;"string"==typeof i?o=t.ownerDocument.querySelectorAll(i):i.querySelector&&(o=[i]),this.previews=o,Mt(o,(function(t){var i=document.createElement("img");zt(t,R,{width:t.offsetWidth,height:t.offsetHeight,html:t.innerHTML}),e&&(i.crossOrigin=e),i.src=a,i.alt=n,i.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',t.innerHTML="",t.appendChild(i)}))}},resetPreview:function(){Mt(this.previews,(function(t){var e=It(t,R);Et(t,{width:e.width,height:e.height}),t.innerHTML=e.html,Wt(t,R)}))},preview:function(){var t=this.imageData,e=this.canvasData,i=this.cropBoxData,a=i.width,n=i.height,r=t.width,o=t.height,h=i.left-e.left-t.left,s=i.top-e.top-t.top;this.cropped&&!this.disabled&&(Et(this.viewBoxImage,Ct({width:r,height:o},Zt(Ct({translateX:-h,translateY:-s},t)))),Mt(this.previews,(function(e){var i=It(e,R),c=i.width,l=i.height,p=c,d=l,u=1;a&&(d=n*(u=c/a)),n&&d>l&&(p=a*(u=l/n),d=l),Et(e,{width:p,height:d}),Et(e.getElementsByTagName("img")[0],Ct({width:r*u,height:o*u},Zt(Ct({translateX:-h*u,translateY:-s*u},t))))})))}},ce={bind:function(){var t=this.element,e=this.options,i=this.cropper;bt(e.cropstart)&&_t(t,F,e.cropstart),bt(e.cropmove)&&_t(t,U,e.cropmove),bt(e.cropend)&&_t(t,P,e.cropend),bt(e.crop)&&_t(t,Y,e.crop),bt(e.zoom)&&_t(t,it,e.zoom),_t(i,$,this.onCropStart=this.cropStart.bind(this)),e.zoomable&&e.zoomOnWheel&&_t(i,et,this.onWheel=this.wheel.bind(this),{passive:!1,capture:!0}),e.toggleDragModeOnDblclick&&_t(i,q,this.onDblclick=this.dblclick.bind(this)),_t(t.ownerDocument,K,this.onCropMove=this.cropMove.bind(this)),_t(t.ownerDocument,G,this.onCropEnd=this.cropEnd.bind(this)),e.responsive&&_t(window,tt,this.onResize=this.resize.bind(this))},unbind:function(){var t=this.element,e=this.options,i=this.cropper;bt(e.cropstart)&&jt(t,F,e.cropstart),bt(e.cropmove)&&jt(t,U,e.cropmove),bt(e.cropend)&&jt(t,P,e.cropend),bt(e.crop)&&jt(t,Y,e.crop),bt(e.zoom)&&jt(t,it,e.zoom),jt(i,$,this.onCropStart),e.zoomable&&e.zoomOnWheel&&jt(i,et,this.onWheel,{passive:!1,capture:!0}),e.toggleDragModeOnDblclick&&jt(i,q,this.onDblclick),jt(t.ownerDocument,K,this.onCropMove),jt(t.ownerDocument,G,this.onCropEnd),e.responsive&&jt(window,tt,this.onResize)}},le={resize:function(){if(!this.disabled){var t,e,i=this.options,a=this.container,n=this.containerData,r=a.offsetWidth/n.width,o=a.offsetHeight/n.height,h=Math.abs(r-1)>Math.abs(o-1)?r:o;1!==h&&(i.restore&&(t=this.getCanvasData(),e=this.getCropBoxData()),this.render(),i.restore&&(this.setCanvasData(Mt(t,(function(e,i){t[i]=e*h}))),this.setCropBoxData(Mt(e,(function(t,i){e[i]=t*h})))))}},dblclick:function(){this.disabled||this.options.dragMode===X||this.setDragMode(At(this.dragBox,O)?_:j)},wheel:function(t){var e=this,i=Number(this.options.wheelZoomRatio)||.1,a=1;this.disabled||(t.preventDefault(),this.wheeling||(this.wheeling=!0,setTimeout((function(){e.wheeling=!1}),50),t.deltaY?a=t.deltaY>0?1:-1:t.wheelDelta?a=-t.wheelDelta/120:t.detail&&(a=t.detail>0?1:-1),this.zoom(-a*i,t)))},cropStart:function(t){var e=t.buttons,i=t.button;if(!(this.disabled||("mousedown"===t.type||"pointerdown"===t.type&&"mouse"===t.pointerType)&&(ut(e)&&1!==e||ut(i)&&0!==i||t.ctrlKey))){var a,n=this.options,r=this.pointers;t.changedTouches?Mt(t.changedTouches,(function(t){r[t.identifier]=Vt(t)})):r[t.pointerId||0]=Vt(t),a=Object.keys(r).length>1&&n.zoomable&&n.zoomOnTouch?x:It(t.target,L),nt.test(a)&&!1!==Xt(this.element,F,{originalEvent:t,action:a})&&(t.preventDefault(),this.action=a,this.cropping=!1,a===b&&(this.cropping=!0,Tt(this.dragBox,z)))}},cropMove:function(t){var e=this.action;if(!this.disabled&&e){var i=this.pointers;t.preventDefault(),!1!==Xt(this.element,U,{originalEvent:t,action:e})&&(t.changedTouches?Mt(t.changedTouches,(function(t){Ct(i[t.identifier]||{},Vt(t,!0))})):Ct(i[t.pointerId||0]||{},Vt(t,!0)),this.change(t))}},cropEnd:function(t){if(!this.disabled){var e=this.action,i=this.pointers;t.changedTouches?Mt(t.changedTouches,(function(t){delete i[t.identifier]})):delete i[t.pointerId||0],e&&(t.preventDefault(),Object.keys(i).length||(this.action=""),this.cropping&&(this.cropping=!1,Nt(this.dragBox,z,this.cropped&&this.options.modal)),Xt(this.element,P,{originalEvent:t,action:e}))}}},pe={change:function(t){var e,i=this.options,a=this.canvasData,n=this.containerData,r=this.cropBoxData,o=this.pointers,h=this.action,s=i.aspectRatio,c=r.left,l=r.top,p=r.width,d=r.height,u=c+p,g=l+d,m=0,f=0,v=n.width,O=n.height,N=!0;!s&&t.shiftKey&&(s=p&&d?p/d:1),this.limited&&(m=r.minLeft,f=r.minTop,v=m+Math.min(n.width,a.width,a.left+a.width),O=f+Math.min(n.height,a.height,a.top+a.height));var S=o[Object.keys(o)[0]],I={x:S.endX-S.startX,y:S.endY-S.startY},z=function(t){switch(t){case M:u+I.x>v&&(I.x=v-u);break;case C:c+I.xO&&(I.y=O-g)}};switch(h){case w:c+=I.x,l+=I.y;break;case M:if(I.x>=0&&(u>=v||s&&(l<=f||g>=O))){N=!1;break}z(M),(p+=I.x)<0&&(h=C,c-=p=-p),s&&(d=p/s,l+=(r.height-d)/2);break;case B:if(I.y<=0&&(l<=f||s&&(c<=m||u>=v))){N=!1;break}z(B),d-=I.y,l+=I.y,d<0&&(h=k,l-=d=-d),s&&(p=d*s,c+=(r.width-p)/2);break;case C:if(I.x<=0&&(c<=m||s&&(l<=f||g>=O))){N=!1;break}z(C),p-=I.x,c+=I.x,p<0&&(h=M,c-=p=-p),s&&(d=p/s,l+=(r.height-d)/2);break;case k:if(I.y>=0&&(g>=O||s&&(c<=m||u>=v))){N=!1;break}z(k),(d+=I.y)<0&&(h=B,l-=d=-d),s&&(p=d*s,c+=(r.width-p)/2);break;case D:if(s){if(I.y<=0&&(l<=f||u>=v)){N=!1;break}z(B),d-=I.y,l+=I.y,p=d*s}else z(B),z(M),I.x>=0?uf&&(d-=I.y,l+=I.y):(d-=I.y,l+=I.y);p<0&&d<0?(h=T,l-=d=-d,c-=p=-p):p<0?(h=E,c-=p=-p):d<0&&(h=A,l-=d=-d);break;case E:if(s){if(I.y<=0&&(l<=f||c<=m)){N=!1;break}z(B),d-=I.y,l+=I.y,p=d*s,c+=r.width-p}else z(B),z(C),I.x<=0?c>m?(p-=I.x,c+=I.x):I.y<=0&&l<=f&&(N=!1):(p-=I.x,c+=I.x),I.y<=0?l>f&&(d-=I.y,l+=I.y):(d-=I.y,l+=I.y);p<0&&d<0?(h=A,l-=d=-d,c-=p=-p):p<0?(h=D,c-=p=-p):d<0&&(h=T,l-=d=-d);break;case T:if(s){if(I.x<=0&&(c<=m||g>=O)){N=!1;break}z(C),p-=I.x,c+=I.x,d=p/s}else z(k),z(C),I.x<=0?c>m?(p-=I.x,c+=I.x):I.y>=0&&g>=O&&(N=!1):(p-=I.x,c+=I.x),I.y>=0?g=0&&(u>=v||g>=O)){N=!1;break}z(M),d=(p+=I.x)/s}else z(k),z(M),I.x>=0?u=0&&g>=O&&(N=!1):p+=I.x,I.y>=0?g0?h=I.y>0?A:D:I.x<0&&(c-=p,h=I.y>0?T:E),I.y<0&&(l-=d),this.cropped||(Ot(this.cropBox,H),this.cropped=!0,this.limited&&this.limitCropBox(!0,!0))}N&&(r.width=p,r.height=d,r.left=c,r.top=l,this.action=h,this.renderCropBox()),Mt(o,(function(t){t.startX=t.endX,t.startY=t.endY}))}},de={crop:function(){return!this.ready||this.cropped||this.disabled||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&Tt(this.dragBox,z),Ot(this.cropBox,H),this.setCropBoxData(this.initialCropBoxData)),this},reset:function(){return this.ready&&!this.disabled&&(this.imageData=Ct({},this.initialImageData),this.canvasData=Ct({},this.initialCanvasData),this.cropBoxData=Ct({},this.initialCropBoxData),this.renderCanvas(),this.cropped&&this.renderCropBox()),this},clear:function(){return this.cropped&&!this.disabled&&(Ct(this.cropBoxData,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),Ot(this.dragBox,z),Tt(this.cropBox,H)),this},replace:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return!this.disabled&&t&&(this.isImg&&(this.element.src=t),e?(this.url=t,this.image.src=t,this.ready&&(this.viewBoxImage.src=t,Mt(this.previews,(function(e){e.getElementsByTagName("img")[0].src=t})))):(this.isImg&&(this.replaced=!0),this.options.data=null,this.uncreate(),this.load(t))),this},enable:function(){return this.ready&&this.disabled&&(this.disabled=!1,Ot(this.cropper,N)),this},disable:function(){return this.ready&&!this.disabled&&(this.disabled=!0,Tt(this.cropper,N)),this},destroy:function(){var t=this.element;return t[v]?(t[v]=void 0,this.isImg&&this.replaced&&(t.src=this.originalUrl),this.uncreate(),this):this},move:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,i=this.canvasData,a=i.left,n=i.top;return this.moveTo(mt(t)?t:a+Number(t),mt(e)?e:n+Number(e))},moveTo:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,i=this.canvasData,a=!1;return t=Number(t),e=Number(e),this.ready&&!this.disabled&&this.options.movable&&(ut(t)&&(i.left=t,a=!0),ut(e)&&(i.top=e,a=!0),a&&this.renderCanvas(!0)),this},zoom:function(t,e){var i=this.canvasData;return t=(t=Number(t))<0?1/(1-t):1+t,this.zoomTo(i.width*t/i.naturalWidth,null,e)},zoomTo:function(t,e,i){var a=this.options,n=this.canvasData,r=n.width,o=n.height,h=n.naturalWidth,s=n.naturalHeight;if((t=Number(t))>=0&&this.ready&&!this.disabled&&a.zoomable){var c=h*t,l=s*t;if(!1===Xt(this.element,it,{ratio:t,oldRatio:r/h,originalEvent:i}))return this;if(i){var p=this.pointers,d=Yt(this.cropper),u=p&&Object.keys(p).length?$t(p):{pageX:i.pageX,pageY:i.pageY};n.left-=(c-r)*((u.pageX-d.left-n.left)/r),n.top-=(l-o)*((u.pageY-d.top-n.top)/o)}else wt(e)&&ut(e.x)&&ut(e.y)?(n.left-=(c-r)*((e.x-n.left)/r),n.top-=(l-o)*((e.y-n.top)/o)):(n.left-=(c-r)/2,n.top-=(l-o)/2);n.width=c,n.height=l,this.renderCanvas(!0)}return this},rotate:function(t){return this.rotateTo((this.imageData.rotate||0)+Number(t))},rotateTo:function(t){return ut(t=Number(t))&&this.ready&&!this.disabled&&this.options.rotatable&&(this.imageData.rotate=t%360,this.renderCanvas(!0,!0)),this},scaleX:function(t){var e=this.imageData.scaleY;return this.scale(t,ut(e)?e:1)},scaleY:function(t){var e=this.imageData.scaleX;return this.scale(ut(e)?e:1,t)},scale:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,i=this.imageData,a=!1;return t=Number(t),e=Number(e),this.ready&&!this.disabled&&this.options.scalable&&(ut(t)&&(i.scaleX=t,a=!0),ut(e)&&(i.scaleY=e,a=!0),a&&this.renderCanvas(!0,!0)),this},getData:function(){var t,e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.options,a=this.imageData,n=this.canvasData,r=this.cropBoxData;if(this.ready&&this.cropped){t={x:r.left-n.left,y:r.top-n.top,width:r.width,height:r.height};var o=a.width/a.naturalWidth;if(Mt(t,(function(e,i){t[i]=e/o})),e){var h=Math.round(t.y+t.height),s=Math.round(t.x+t.width);t.x=Math.round(t.x),t.y=Math.round(t.y),t.width=s-t.x,t.height=h-t.y}}else t={x:0,y:0,width:0,height:0};return i.rotatable&&(t.rotate=a.rotate||0),i.scalable&&(t.scaleX=a.scaleX||1,t.scaleY=a.scaleY||1),t},setData:function(t){var e=this.options,i=this.imageData,a=this.canvasData,n={};if(this.ready&&!this.disabled&&wt(t)){var r=!1;e.rotatable&&ut(t.rotate)&&t.rotate!==i.rotate&&(i.rotate=t.rotate,r=!0),e.scalable&&(ut(t.scaleX)&&t.scaleX!==i.scaleX&&(i.scaleX=t.scaleX,r=!0),ut(t.scaleY)&&t.scaleY!==i.scaleY&&(i.scaleY=t.scaleY,r=!0)),r&&this.renderCanvas(!0,!0);var o=i.width/i.naturalWidth;ut(t.x)&&(n.left=t.x*o+a.left),ut(t.y)&&(n.top=t.y*o+a.top),ut(t.width)&&(n.width=t.width*o),ut(t.height)&&(n.height=t.height*o),this.setCropBoxData(n)}return this},getContainerData:function(){return this.ready?Ct({},this.containerData):{}},getImageData:function(){return this.sized?Ct({},this.imageData):{}},getCanvasData:function(){var t=this.canvasData,e={};return this.ready&&Mt(["left","top","width","height","naturalWidth","naturalHeight"],(function(i){e[i]=t[i]})),e},setCanvasData:function(t){var e=this.canvasData,i=e.aspectRatio;return this.ready&&!this.disabled&&wt(t)&&(ut(t.left)&&(e.left=t.left),ut(t.top)&&(e.top=t.top),ut(t.width)?(e.width=t.width,e.height=t.width/i):ut(t.height)&&(e.height=t.height,e.width=t.height*i),this.renderCanvas(!0)),this},getCropBoxData:function(){var t,e=this.cropBoxData;return this.ready&&this.cropped&&(t={left:e.left,top:e.top,width:e.width,height:e.height}),t||{}},setCropBoxData:function(t){var e,i,a=this.cropBoxData,n=this.options.aspectRatio;return this.ready&&this.cropped&&!this.disabled&&wt(t)&&(ut(t.left)&&(a.left=t.left),ut(t.top)&&(a.top=t.top),ut(t.width)&&t.width!==a.width&&(e=!0,a.width=t.width),ut(t.height)&&t.height!==a.height&&(i=!0,a.height=t.height),n&&(e?a.height=a.width/n:i&&(a.width=a.height*n)),this.renderCropBox()),this},getCroppedCanvas:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!this.ready||!window.HTMLCanvasElement)return null;var e=this.canvasData,i=Jt(this.image,this.imageData,e,t);if(!this.cropped)return i;var a=this.getData(),n=a.x,r=a.y,o=a.width,s=a.height,c=i.width/Math.floor(e.naturalWidth);1!==c&&(n*=c,r*=c,o*=c,s*=c);var l=o/s,p=Kt({aspectRatio:l,width:t.maxWidth||1/0,height:t.maxHeight||1/0}),d=Kt({aspectRatio:l,width:t.minWidth||0,height:t.minHeight||0},"cover"),u=Kt({aspectRatio:l,width:t.width||(1!==c?i.width:o),height:t.height||(1!==c?i.height:s)}),g=u.width,m=u.height;g=Math.min(p.width,Math.max(d.width,g)),m=Math.min(p.height,Math.max(d.height,m));var f=document.createElement("canvas"),v=f.getContext("2d");f.width=Bt(g),f.height=Bt(m),v.fillStyle=t.fillColor||"transparent",v.fillRect(0,0,g,m);var w=t.imageSmoothingEnabled,b=void 0===w||w,y=t.imageSmoothingQuality;v.imageSmoothingEnabled=b,y&&(v.imageSmoothingQuality=y);var x,M,C,k,B,D,E=i.width,A=i.height,T=n,O=r;T<=-o||T>E?(T=0,x=0,C=0,B=0):T<=0?(C=-T,T=0,B=x=Math.min(E,o+T)):T<=E&&(C=0,B=x=Math.min(o,E-T)),x<=0||O<=-s||O>A?(O=0,M=0,k=0,D=0):O<=0?(k=-O,O=0,D=M=Math.min(A,s+O)):O<=A&&(k=0,D=M=Math.min(s,A-O));var N=[T,O,x,M];if(B>0&&D>0){var H=g/o;N.push(C*H,k*H,B*H,D*H)}return v.drawImage.apply(v,[i].concat(h(N.map((function(t){return Math.floor(Bt(t))}))))),f},setAspectRatio:function(t){var e=this.options;return this.disabled||mt(t)||(e.aspectRatio=Math.max(0,t)||NaN,this.ready&&(this.initCropBox(),this.cropped&&this.renderCropBox())),this},setDragMode:function(t){var e=this.options,i=this.dragBox,a=this.face;if(this.ready&&!this.disabled){var n=t===j,r=e.movable&&t===_;t=n||r?t:X,e.dragMode=t,zt(i,L,t),Nt(i,O,n),Nt(i,W,r),e.cropBoxMovable||(zt(a,L,t),Nt(a,O,n),Nt(a,W,r))}return this}},ue=g.Cropper,ge=function(){function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(a(this,t),!e||!ht.test(e.tagName))throw new Error("The first argument is required and must be an or element.");this.element=e,this.options=Ct({},lt,wt(i)&&i),this.cropped=!1,this.disabled=!1,this.pointers={},this.ready=!1,this.reloading=!1,this.replaced=!1,this.sized=!1,this.sizing=!1,this.init()}return r(t,[{key:"init",value:function(){var t,e=this.element,i=e.tagName.toLowerCase();if(!e[v]){if(e[v]=this,"img"===i){if(this.isImg=!0,t=e.getAttribute("src")||"",this.originalUrl=t,!t)return;t=e.src}else"canvas"===i&&window.HTMLCanvasElement&&(t=e.toDataURL());this.load(t)}}},{key:"load",value:function(t){var e=this;if(t){this.url=t,this.imageData={};var i=this.element,a=this.options;if(a.rotatable||a.scalable||(a.checkOrientation=!1),a.checkOrientation&&window.ArrayBuffer)if(rt.test(t))ot.test(t)?this.read(ae(t)):this.clone();else{var n=new XMLHttpRequest,r=this.clone.bind(this);this.reloading=!0,this.xhr=n,n.onabort=r,n.onerror=r,n.ontimeout=r,n.onprogress=function(){n.getResponseHeader("content-type")!==at&&n.abort()},n.onload=function(){e.read(n.response)},n.onloadend=function(){e.reloading=!1,e.xhr=null},a.checkCrossOrigin&&Ft(t)&&i.crossOrigin&&(t=qt(t)),n.open("GET",t,!0),n.responseType="arraybuffer",n.withCredentials="use-credentials"===i.crossOrigin,n.send()}else this.clone()}}},{key:"read",value:function(t){var e=this.options,i=this.imageData,a=re(t),n=0,r=1,o=1;if(a>1){this.url=ne(t,at);var h=oe(a);n=h.rotate,r=h.scaleX,o=h.scaleY}e.rotatable&&(i.rotate=n),e.scalable&&(i.scaleX=r,i.scaleY=o),this.clone()}},{key:"clone",value:function(){var t=this.element,e=this.url,i=t.crossOrigin,a=e;this.options.checkCrossOrigin&&Ft(e)&&(i||(i="anonymous"),a=qt(e)),this.crossOrigin=i,this.crossOriginUrl=a;var n=document.createElement("img");i&&(n.crossOrigin=i),n.src=a||e,n.alt=t.alt||"The image to crop",this.image=n,n.onload=this.start.bind(this),n.onerror=this.stop.bind(this),Tt(n,S),t.parentNode.insertBefore(n,t.nextSibling)}},{key:"start",value:function(){var t=this,e=this.image;e.onload=null,e.onerror=null,this.sizing=!0;var i=g.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(g.navigator.userAgent),a=function(e,i){Ct(t.imageData,{naturalWidth:e,naturalHeight:i,aspectRatio:e/i}),t.initialImageData=Ct({},t.imageData),t.sizing=!1,t.sized=!0,t.build()};if(!e.naturalWidth||i){var n=document.createElement("img"),r=document.body||document.documentElement;this.sizingImage=n,n.onload=function(){a(n.width,n.height),i||r.removeChild(n)},n.src=e.src,i||(n.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",r.appendChild(n))}else a(e.naturalWidth,e.naturalHeight)}},{key:"stop",value:function(){var t=this.image;t.onload=null,t.onerror=null,t.parentNode.removeChild(t),this.image=null}},{key:"build",value:function(){if(this.sized&&!this.ready){var t=this.element,e=this.options,i=this.image,a=t.parentNode,n=document.createElement("div");n.innerHTML=pt;var r=n.querySelector(".".concat(v,"-container")),o=r.querySelector(".".concat(v,"-canvas")),h=r.querySelector(".".concat(v,"-drag-box")),s=r.querySelector(".".concat(v,"-crop-box")),c=s.querySelector(".".concat(v,"-face"));this.container=a,this.cropper=r,this.canvas=o,this.dragBox=h,this.cropBox=s,this.viewBox=r.querySelector(".".concat(v,"-view-box")),this.face=c,o.appendChild(i),Tt(t,H),a.insertBefore(r,t.nextSibling),Ot(i,S),this.initPreview(),this.bind(),e.initialAspectRatio=Math.max(0,e.initialAspectRatio)||NaN,e.aspectRatio=Math.max(0,e.aspectRatio)||NaN,e.viewMode=Math.max(0,Math.min(3,Math.round(e.viewMode)))||0,Tt(s,H),e.guides||Tt(s.getElementsByClassName("".concat(v,"-dashed")),H),e.center||Tt(s.getElementsByClassName("".concat(v,"-center")),H),e.background&&Tt(r,"".concat(v,"-bg")),e.highlight||Tt(c,I),e.cropBoxMovable&&(Tt(c,W),zt(c,L,w)),e.cropBoxResizable||(Tt(s.getElementsByClassName("".concat(v,"-line")),H),Tt(s.getElementsByClassName("".concat(v,"-point")),H)),this.render(),this.ready=!0,this.setDragMode(e.dragMode),e.autoCrop&&this.crop(),this.setData(e.data),bt(e.ready)&&_t(t,J,e.ready,{once:!0}),Xt(t,J)}}},{key:"unbuild",value:function(){if(this.ready){this.ready=!1,this.unbind(),this.resetPreview();var t=this.cropper.parentNode;t&&t.removeChild(this.cropper),Ot(this.element,H)}}},{key:"uncreate",value:function(){this.ready?(this.unbuild(),this.ready=!1,this.cropped=!1):this.sizing?(this.sizingImage.onload=null,this.sizing=!1,this.sized=!1):this.reloading?(this.xhr.onabort=null,this.xhr.abort()):this.image&&this.stop()}}],[{key:"noConflict",value:function(){return window.Cropper=ue,t}},{key:"setDefaults",value:function(t){Ct(lt,wt(t)&&t)}}]),t}();return Ct(ge.prototype,he,se,ce,le,pe,de),ge}()},722:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});var a=i(645),n=i.n(a)()((function(t){return t[1]}));n.push([t.id,'/*!\n * Cropper.js v1.5.13\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2022-11-20T05:30:43.444Z\n */.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{image-orientation:0deg;-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;height:100%;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}',""]);const r=n},645:t=>{"use strict";t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var i=t(e);return e[2]?"@media ".concat(e[2]," {").concat(i,"}"):i})).join("")},e.i=function(t,i,a){"string"==typeof t&&(t=[[null,t,""]]);var n={};if(a)for(var r=0;r{"use strict";var a,n=function(){return void 0===a&&(a=Boolean(window&&document&&document.all&&!window.atob)),a},r=function(){var t={};return function(e){if(void 0===t[e]){var i=document.querySelector(e);if(window.HTMLIFrameElement&&i instanceof window.HTMLIFrameElement)try{i=i.contentDocument.head}catch(t){i=null}t[e]=i}return t[e]}}(),o=[];function h(t){for(var e=-1,i=0;i{var e;e=961,t(t.s=e)}]); \ No newline at end of file diff --git a/public/js/crop-image.js.LICENSE.txt b/public/js/crop-image.js.LICENSE.txt new file mode 100644 index 0000000..337201f --- /dev/null +++ b/public/js/crop-image.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! + * Cropper.js v1.5.13 + * https://fengyuanchen.github.io/cropperjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2022-11-20T05:30:46.114Z + */ diff --git a/public/js/file-download.js b/public/js/file-download.js new file mode 100644 index 0000000..abe63e3 --- /dev/null +++ b/public/js/file-download.js @@ -0,0 +1 @@ +(self.webpackChunk=self.webpackChunk||[]).push([[268],{149:()=>{window.fileDownload=function(){return{save:function(e,n,o,c){var d=new Blob([n],{type:o}),a=window.document.createElement("a");a.href=window.URL.createObjectURL(d),a.download="".concat(e,".").concat(c),document.body.appendChild(a),a.click(),document.body.removeChild(a)}}}}},e=>{var n;n=149,e(e.s=n)}]); \ No newline at end of file diff --git a/public/js/file-upload.js b/public/js/file-upload.js new file mode 100644 index 0000000..545d344 --- /dev/null +++ b/public/js/file-upload.js @@ -0,0 +1,49 @@ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["/js/file-upload"],{ + +/***/ "./resources/js/file-upload.js": +/*!*************************************!*\ + !*** ./resources/js/file-upload.js ***! + \*************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +window.uploadPhoto = function (_ref) { + var url = _ref.url, + onUpload = _ref.onUpload; + return { + url: url, + onUpload: onUpload, + upload: function upload(e) { + var _this = this; + + if (!e.target.files.length) return; + var data = new FormData(); + data.append('logo', e.target.files[0]); + fetch(this.url, { + method: 'POST', + body: data + }).then(function () { + return _this.onUpload(); + }); + }, + select: function select() { + document.getElementById('photo').click(); + } + }; +}; + +/***/ }), + +/***/ 1: +/*!*******************************************!*\ + !*** multi ./resources/js/file-upload.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(/*! /Users/josip/Work/deployer/resources/js/file-upload.js */"./resources/js/file-upload.js"); + + +/***/ }) + +},[[1,"/js/manifest"]]]); \ No newline at end of file diff --git a/public/js/manifest.js b/public/js/manifest.js new file mode 100644 index 0000000..274efe4 --- /dev/null +++ b/public/js/manifest.js @@ -0,0 +1 @@ +(()=>{"use strict";var r,e={},o={};function t(r){var n=o[r];if(void 0!==n)return n.exports;var a=o[r]={id:r,exports:{}};return e[r].call(a.exports,a,a.exports,t),a.exports}t.m=e,r=[],t.O=(e,o,n,a)=>{if(!o){var l=1/0;for(u=0;u=a)&&Object.keys(t.O).every((r=>t.O[r](o[f])))?o.splice(f--,1):(i=!1,a0&&r[u-1][2]>a;u--)r[u]=r[u-1];r[u]=[o,n,a]},t.n=r=>{var e=r&&r.__esModule?()=>r.default:()=>r;return t.d(e,{a:e}),e},t.d=(r,e)=>{for(var o in e)t.o(e,o)&&!t.o(r,o)&&Object.defineProperty(r,o,{enumerable:!0,get:e[o]})},t.o=(r,e)=>Object.prototype.hasOwnProperty.call(r,e),(()=>{var r={929:0,170:0};t.O.j=e=>0===r[e];var e=(e,o)=>{var n,a,[l,i,f]=o,s=0;if(l.some((e=>0!==r[e]))){for(n in i)t.o(i,n)&&(t.m[n]=i[n]);if(f)var u=f(t)}for(e&&e(o);s{void 0===s[i]?s[i]=a[i]:e(a[i])&&e(s[i])&&Object.keys(a[i]).length>0&&t(s[i],a[i])}))}const s={body:{},addEventListener(){},removeEventListener(){},activeElement:{blur(){},nodeName:""},querySelector:()=>null,querySelectorAll:()=>[],getElementById:()=>null,createEvent:()=>({initEvent(){}}),createElement:()=>({children:[],childNodes:[],style:{},setAttribute(){},getElementsByTagName:()=>[]}),createElementNS:()=>({}),importNode:()=>null,location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function a(){const e="undefined"!=typeof document?document:{};return t(e,s),e}const i={document:s,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState(){},pushState(){},go(){},back(){}},CustomEvent:function(){return this},addEventListener(){},removeEventListener(){},getComputedStyle:()=>({getPropertyValue:()=>""}),Image(){},Date(){},screen:{},setTimeout(){},clearTimeout(){},matchMedia:()=>({}),requestAnimationFrame:e=>"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0),cancelAnimationFrame(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function r(){const e="undefined"!=typeof window?window:{};return t(e,i),e}class n extends Array{constructor(e){"number"==typeof e?super(e):(super(...e||[]),function(e){const t=e.__proto__;Object.defineProperty(e,"__proto__",{get:()=>t,set(e){t.__proto__=e}})}(this))}}function l(e){void 0===e&&(e=[]);const t=[];return e.forEach((e=>{Array.isArray(e)?t.push(...l(e)):t.push(e)})),t}function o(e,t){return Array.prototype.filter.call(e,t)}function d(e,t){const s=r(),i=a();let l=[];if(!t&&e instanceof n)return e;if(!e)return new n(l);if("string"==typeof e){const s=e.trim();if(s.indexOf("<")>=0&&s.indexOf(">")>=0){let e="div";0===s.indexOf("e.split(" "))));return this.forEach((e=>{e.classList.add(...a)})),this},removeClass:function(){for(var e=arguments.length,t=new Array(e),s=0;se.split(" "))));return this.forEach((e=>{e.classList.remove(...a)})),this},hasClass:function(){for(var e=arguments.length,t=new Array(e),s=0;se.split(" "))));return o(this,(e=>a.filter((t=>e.classList.contains(t))).length>0)).length>0},toggleClass:function(){for(var e=arguments.length,t=new Array(e),s=0;se.split(" "))));this.forEach((e=>{a.forEach((t=>{e.classList.toggle(t)}))}))},attr:function(e,t){if(1===arguments.length&&"string"==typeof e)return this[0]?this[0].getAttribute(e):void 0;for(let s=0;s=0;e-=1){const i=a[e];r&&i.listener===r||r&&i.listener&&i.listener.dom7proxy&&i.listener.dom7proxy===r?(s.removeEventListener(t,i.proxyListener,n),a.splice(e,1)):r||(s.removeEventListener(t,i.proxyListener,n),a.splice(e,1))}}}return this},trigger:function(){const e=r();for(var t=arguments.length,s=new Array(t),a=0;at>0)),i.dispatchEvent(t),i.dom7EventData=[],delete i.dom7EventData}}}return this},transitionEnd:function(e){const t=this;return e&&t.on("transitionend",(function s(a){a.target===this&&(e.call(this,a),t.off("transitionend",s))})),this},outerWidth:function(e){if(this.length>0){if(e){const e=this.styles();return this[0].offsetWidth+parseFloat(e.getPropertyValue("margin-right"))+parseFloat(e.getPropertyValue("margin-left"))}return this[0].offsetWidth}return null},outerHeight:function(e){if(this.length>0){if(e){const e=this.styles();return this[0].offsetHeight+parseFloat(e.getPropertyValue("margin-top"))+parseFloat(e.getPropertyValue("margin-bottom"))}return this[0].offsetHeight}return null},styles:function(){const e=r();return this[0]?e.getComputedStyle(this[0],null):{}},offset:function(){if(this.length>0){const e=r(),t=a(),s=this[0],i=s.getBoundingClientRect(),n=t.body,l=s.clientTop||n.clientTop||0,o=s.clientLeft||n.clientLeft||0,d=s===e?e.scrollY:s.scrollTop,c=s===e?e.scrollX:s.scrollLeft;return{top:i.top+d-l,left:i.left+c-o}}return null},css:function(e,t){const s=r();let a;if(1===arguments.length){if("string"!=typeof e){for(a=0;a{e.apply(t,[t,s])})),this):this},html:function(e){if(void 0===e)return this[0]?this[0].innerHTML:null;for(let t=0;tt-1)return d([]);if(e<0){const s=t+e;return d(s<0?[]:[this[s]])}return d([this[e]])},append:function(){let e;const t=a();for(let s=0;s=0;i-=1)this[s].insertBefore(a.childNodes[i],this[s].childNodes[0])}else if(e instanceof n)for(i=0;i0?e?this[0].nextElementSibling&&d(this[0].nextElementSibling).is(e)?d([this[0].nextElementSibling]):d([]):this[0].nextElementSibling?d([this[0].nextElementSibling]):d([]):d([])},nextAll:function(e){const t=[];let s=this[0];if(!s)return d([]);for(;s.nextElementSibling;){const a=s.nextElementSibling;e?d(a).is(e)&&t.push(a):t.push(a),s=a}return d(t)},prev:function(e){if(this.length>0){const t=this[0];return e?t.previousElementSibling&&d(t.previousElementSibling).is(e)?d([t.previousElementSibling]):d([]):t.previousElementSibling?d([t.previousElementSibling]):d([])}return d([])},prevAll:function(e){const t=[];let s=this[0];if(!s)return d([]);for(;s.previousElementSibling;){const a=s.previousElementSibling;e?d(a).is(e)&&t.push(a):t.push(a),s=a}return d(t)},parent:function(e){const t=[];for(let s=0;s6&&(i=i.split(", ").map((e=>e.replace(",","."))).join(", ")),n=new s.WebKitCSSMatrix("none"===i?"":i)):(n=l.MozTransform||l.OTransform||l.MsTransform||l.msTransform||l.transform||l.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),a=n.toString().split(",")),"x"===t&&(i=s.WebKitCSSMatrix?n.m41:16===a.length?parseFloat(a[12]):parseFloat(a[4])),"y"===t&&(i=s.WebKitCSSMatrix?n.m42:16===a.length?parseFloat(a[13]):parseFloat(a[5])),i||0}function m(e){return"object"==typeof e&&null!==e&&e.constructor&&"Object"===Object.prototype.toString.call(e).slice(8,-1)}function f(e){return"undefined"!=typeof window&&void 0!==window.HTMLElement?e instanceof HTMLElement:e&&(1===e.nodeType||11===e.nodeType)}function g(){const e=Object(arguments.length<=0?void 0:arguments[0]),t=["__proto__","constructor","prototype"];for(let s=1;st.indexOf(e)<0));for(let t=0,i=s.length;tn?"next":"prev",p=(e,t)=>"next"===c&&e>=t||"prev"===c&&e<=t,u=()=>{l=(new Date).getTime(),null===o&&(o=l);const e=Math.max(Math.min((l-o)/d,1),0),r=.5-Math.cos(e*Math.PI)/2;let c=n+r*(s-n);if(p(c,s)&&(c=s),t.wrapperEl.scrollTo({[a]:c}),p(c,s))return t.wrapperEl.style.overflow="hidden",t.wrapperEl.style.scrollSnapType="",setTimeout((()=>{t.wrapperEl.style.overflow="",t.wrapperEl.scrollTo({[a]:c})})),void i.cancelAnimationFrame(t.cssModeFrameID);t.cssModeFrameID=i.requestAnimationFrame(u)};u()}let b,x,y;function E(){return b||(b=function(){const e=r(),t=a();return{smoothScroll:t.documentElement&&"scrollBehavior"in t.documentElement.style,touch:!!("ontouchstart"in e||e.DocumentTouch&&t instanceof e.DocumentTouch),passiveListener:function(){let t=!1;try{const s=Object.defineProperty({},"passive",{get(){t=!0}});e.addEventListener("testPassiveListener",null,s)}catch(e){}return t}(),gestures:"ongesturestart"in e}}()),b}function C(e){return void 0===e&&(e={}),x||(x=function(e){let{userAgent:t}=void 0===e?{}:e;const s=E(),a=r(),i=a.navigator.platform,n=t||a.navigator.userAgent,l={ios:!1,android:!1},o=a.screen.width,d=a.screen.height,c=n.match(/(Android);?[\s\/]+([\d.]+)?/);let p=n.match(/(iPad).*OS\s([\d_]+)/);const u=n.match(/(iPod)(.*OS\s([\d_]+))?/),h=!p&&n.match(/(iPhone\sOS|iOS)\s([\d_]+)/),m="Win32"===i;let f="MacIntel"===i;return!p&&f&&s.touch&&["1024x1366","1366x1024","834x1194","1194x834","834x1112","1112x834","768x1024","1024x768","820x1180","1180x820","810x1080","1080x810"].indexOf(`${o}x${d}`)>=0&&(p=n.match(/(Version)\/([\d.]+)/),p||(p=[0,1,"13_0_0"]),f=!1),c&&!m&&(l.os="android",l.android=!0),(p||h||u)&&(l.os="ios",l.ios=!0),l}(e)),x}function T(){return y||(y=function(){const e=r();return{isSafari:function(){const t=e.navigator.userAgent.toLowerCase();return t.indexOf("safari")>=0&&t.indexOf("chrome")<0&&t.indexOf("android")<0}(),isWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(e.navigator.userAgent)}}()),y}Object.keys(c).forEach((e=>{Object.defineProperty(d.fn,e,{value:c[e],writable:!0})}));var $={on(e,t,s){const a=this;if(!a.eventsListeners||a.destroyed)return a;if("function"!=typeof t)return a;const i=s?"unshift":"push";return e.split(" ").forEach((e=>{a.eventsListeners[e]||(a.eventsListeners[e]=[]),a.eventsListeners[e][i](t)})),a},once(e,t,s){const a=this;if(!a.eventsListeners||a.destroyed)return a;if("function"!=typeof t)return a;function i(){a.off(e,i),i.__emitterProxy&&delete i.__emitterProxy;for(var s=arguments.length,r=new Array(s),n=0;n=0&&t.eventsAnyListeners.splice(s,1),t},off(e,t){const s=this;return!s.eventsListeners||s.destroyed?s:s.eventsListeners?(e.split(" ").forEach((e=>{void 0===t?s.eventsListeners[e]=[]:s.eventsListeners[e]&&s.eventsListeners[e].forEach(((a,i)=>{(a===t||a.__emitterProxy&&a.__emitterProxy===t)&&s.eventsListeners[e].splice(i,1)}))})),s):s},emit(){const e=this;if(!e.eventsListeners||e.destroyed)return e;if(!e.eventsListeners)return e;let t,s,a;for(var i=arguments.length,r=new Array(i),n=0;n{e.eventsAnyListeners&&e.eventsAnyListeners.length&&e.eventsAnyListeners.forEach((e=>{e.apply(a,[t,...s])})),e.eventsListeners&&e.eventsListeners[t]&&e.eventsListeners[t].forEach((e=>{e.apply(a,s)}))})),e}};var S={updateSize:function(){const e=this;let t,s;const a=e.$el;t=void 0!==e.params.width&&null!==e.params.width?e.params.width:a[0].clientWidth,s=void 0!==e.params.height&&null!==e.params.height?e.params.height:a[0].clientHeight,0===t&&e.isHorizontal()||0===s&&e.isVertical()||(t=t-parseInt(a.css("padding-left")||0,10)-parseInt(a.css("padding-right")||0,10),s=s-parseInt(a.css("padding-top")||0,10)-parseInt(a.css("padding-bottom")||0,10),Number.isNaN(t)&&(t=0),Number.isNaN(s)&&(s=0),Object.assign(e,{width:t,height:s,size:e.isHorizontal()?t:s}))},updateSlides:function(){const e=this;function t(t){return e.isHorizontal()?t:{width:"height","margin-top":"margin-left","margin-bottom ":"margin-right","margin-left":"margin-top","margin-right":"margin-bottom","padding-left":"padding-top","padding-right":"padding-bottom",marginRight:"marginBottom"}[t]}function s(e,s){return parseFloat(e.getPropertyValue(t(s))||0)}const a=e.params,{$wrapperEl:i,size:r,rtlTranslate:n,wrongRTL:l}=e,o=e.virtual&&a.virtual.enabled,d=o?e.virtual.slides.length:e.slides.length,c=i.children(`.${e.params.slideClass}`),p=o?e.virtual.slides.length:c.length;let u=[];const h=[],m=[];let f=a.slidesOffsetBefore;"function"==typeof f&&(f=a.slidesOffsetBefore.call(e));let g=a.slidesOffsetAfter;"function"==typeof g&&(g=a.slidesOffsetAfter.call(e));const w=e.snapGrid.length,b=e.slidesGrid.length;let x=a.spaceBetween,y=-f,E=0,C=0;if(void 0===r)return;"string"==typeof x&&x.indexOf("%")>=0&&(x=parseFloat(x.replace("%",""))/100*r),e.virtualSize=-x,n?c.css({marginLeft:"",marginBottom:"",marginTop:""}):c.css({marginRight:"",marginBottom:"",marginTop:""}),a.centeredSlides&&a.cssMode&&(v(e.wrapperEl,"--swiper-centered-offset-before",""),v(e.wrapperEl,"--swiper-centered-offset-after",""));const T=a.grid&&a.grid.rows>1&&e.grid;let $;T&&e.grid.initSlides(p);const S="auto"===a.slidesPerView&&a.breakpoints&&Object.keys(a.breakpoints).filter((e=>void 0!==a.breakpoints[e].slidesPerView)).length>0;for(let i=0;i1&&u.push(e.virtualSize-r)}if(0===u.length&&(u=[0]),0!==a.spaceBetween){const s=e.isHorizontal()&&n?"marginLeft":t("marginRight");c.filter(((e,t)=>!a.cssMode||t!==c.length-1)).css({[s]:`${x}px`})}if(a.centeredSlides&&a.centeredSlidesBounds){let e=0;m.forEach((t=>{e+=t+(a.spaceBetween?a.spaceBetween:0)})),e-=a.spaceBetween;const t=e-r;u=u.map((e=>e<0?-f:e>t?t+g:e))}if(a.centerInsufficientSlides){let e=0;if(m.forEach((t=>{e+=t+(a.spaceBetween?a.spaceBetween:0)})),e-=a.spaceBetween,e{u[s]=e-t})),h.forEach(((e,s)=>{h[s]=e+t}))}}if(Object.assign(e,{slides:c,snapGrid:u,slidesGrid:h,slidesSizesGrid:m}),a.centeredSlides&&a.cssMode&&!a.centeredSlidesBounds){v(e.wrapperEl,"--swiper-centered-offset-before",-u[0]+"px"),v(e.wrapperEl,"--swiper-centered-offset-after",e.size/2-m[m.length-1]/2+"px");const t=-e.snapGrid[0],s=-e.slidesGrid[0];e.snapGrid=e.snapGrid.map((e=>e+t)),e.slidesGrid=e.slidesGrid.map((e=>e+s))}if(p!==d&&e.emit("slidesLengthChange"),u.length!==w&&(e.params.watchOverflow&&e.checkOverflow(),e.emit("snapGridLengthChange")),h.length!==b&&e.emit("slidesGridLengthChange"),a.watchSlidesProgress&&e.updateSlidesOffset(),!(o||a.cssMode||"slide"!==a.effect&&"fade"!==a.effect)){const t=`${a.containerModifierClass}backface-hidden`,s=e.$el.hasClass(t);p<=a.maxBackfaceHiddenSlides?s||e.$el.addClass(t):s&&e.$el.removeClass(t)}},updateAutoHeight:function(e){const t=this,s=[],a=t.virtual&&t.params.virtual.enabled;let i,r=0;"number"==typeof e?t.setTransition(e):!0===e&&t.setTransition(t.params.speed);const n=e=>a?t.slides.filter((t=>parseInt(t.getAttribute("data-swiper-slide-index"),10)===e))[0]:t.slides.eq(e)[0];if("auto"!==t.params.slidesPerView&&t.params.slidesPerView>1)if(t.params.centeredSlides)(t.visibleSlides||d([])).each((e=>{s.push(e)}));else for(i=0;it.slides.length&&!a)break;s.push(n(e))}else s.push(n(t.activeIndex));for(i=0;ir?e:r}(r||0===r)&&t.$wrapperEl.css("height",`${r}px`)},updateSlidesOffset:function(){const e=this,t=e.slides;for(let s=0;s=0&&p1&&u<=t.size||p<=0&&u>=t.size)&&(t.visibleSlides.push(l),t.visibleSlidesIndexes.push(e),a.eq(e).addClass(s.slideVisibleClass)),l.progress=i?-d:d,l.originalProgress=i?-c:c}t.visibleSlides=d(t.visibleSlides)},updateProgress:function(e){const t=this;if(void 0===e){const s=t.rtlTranslate?-1:1;e=t&&t.translate&&t.translate*s||0}const s=t.params,a=t.maxTranslate()-t.minTranslate();let{progress:i,isBeginning:r,isEnd:n}=t;const l=r,o=n;0===a?(i=0,r=!0,n=!0):(i=(e-t.minTranslate())/a,r=i<=0,n=i>=1),Object.assign(t,{progress:i,isBeginning:r,isEnd:n}),(s.watchSlidesProgress||s.centeredSlides&&s.autoHeight)&&t.updateSlidesProgress(e),r&&!l&&t.emit("reachBeginning toEdge"),n&&!o&&t.emit("reachEnd toEdge"),(l&&!r||o&&!n)&&t.emit("fromEdge"),t.emit("progress",i)},updateSlidesClasses:function(){const e=this,{slides:t,params:s,$wrapperEl:a,activeIndex:i,realIndex:r}=e,n=e.virtual&&s.virtual.enabled;let l;t.removeClass(`${s.slideActiveClass} ${s.slideNextClass} ${s.slidePrevClass} ${s.slideDuplicateActiveClass} ${s.slideDuplicateNextClass} ${s.slideDuplicatePrevClass}`),l=n?e.$wrapperEl.find(`.${s.slideClass}[data-swiper-slide-index="${i}"]`):t.eq(i),l.addClass(s.slideActiveClass),s.loop&&(l.hasClass(s.slideDuplicateClass)?a.children(`.${s.slideClass}:not(.${s.slideDuplicateClass})[data-swiper-slide-index="${r}"]`).addClass(s.slideDuplicateActiveClass):a.children(`.${s.slideClass}.${s.slideDuplicateClass}[data-swiper-slide-index="${r}"]`).addClass(s.slideDuplicateActiveClass));let o=l.nextAll(`.${s.slideClass}`).eq(0).addClass(s.slideNextClass);s.loop&&0===o.length&&(o=t.eq(0),o.addClass(s.slideNextClass));let d=l.prevAll(`.${s.slideClass}`).eq(0).addClass(s.slidePrevClass);s.loop&&0===d.length&&(d=t.eq(-1),d.addClass(s.slidePrevClass)),s.loop&&(o.hasClass(s.slideDuplicateClass)?a.children(`.${s.slideClass}:not(.${s.slideDuplicateClass})[data-swiper-slide-index="${o.attr("data-swiper-slide-index")}"]`).addClass(s.slideDuplicateNextClass):a.children(`.${s.slideClass}.${s.slideDuplicateClass}[data-swiper-slide-index="${o.attr("data-swiper-slide-index")}"]`).addClass(s.slideDuplicateNextClass),d.hasClass(s.slideDuplicateClass)?a.children(`.${s.slideClass}:not(.${s.slideDuplicateClass})[data-swiper-slide-index="${d.attr("data-swiper-slide-index")}"]`).addClass(s.slideDuplicatePrevClass):a.children(`.${s.slideClass}.${s.slideDuplicateClass}[data-swiper-slide-index="${d.attr("data-swiper-slide-index")}"]`).addClass(s.slideDuplicatePrevClass)),e.emitSlidesClasses()},updateActiveIndex:function(e){const t=this,s=t.rtlTranslate?t.translate:-t.translate,{slidesGrid:a,snapGrid:i,params:r,activeIndex:n,realIndex:l,snapIndex:o}=t;let d,c=e;if(void 0===c){for(let e=0;e=a[e]&&s=a[e]&&s=a[e]&&(c=e);r.normalizeSlideIndex&&(c<0||void 0===c)&&(c=0)}if(i.indexOf(s)>=0)d=i.indexOf(s);else{const e=Math.min(r.slidesPerGroupSkip,c);d=e+Math.floor((c-e)/r.slidesPerGroup)}if(d>=i.length&&(d=i.length-1),c===n)return void(d!==o&&(t.snapIndex=d,t.emit("snapIndexChange")));const p=parseInt(t.slides.eq(c).attr("data-swiper-slide-index")||c,10);Object.assign(t,{snapIndex:d,realIndex:p,previousIndex:n,activeIndex:c}),t.emit("activeIndexChange"),t.emit("snapIndexChange"),l!==p&&t.emit("realIndexChange"),(t.initialized||t.params.runCallbacksOnInit)&&t.emit("slideChange")},updateClickedSlide:function(e){const t=this,s=t.params,a=d(e).closest(`.${s.slideClass}`)[0];let i,r=!1;if(a)for(let e=0;eo?o:a&&en?"next":r=o.length&&(g=o.length-1);const v=-o[g];if(l.normalizeSlideIndex)for(let e=0;e=s&&t=s&&t=s&&(n=e)}if(r.initialized&&n!==p){if(!r.allowSlideNext&&vr.translate&&v>r.maxTranslate()&&(p||0)!==n)return!1}let b;if(n!==(c||0)&&s&&r.emit("beforeSlideChangeStart"),r.updateProgress(v),b=n>p?"next":n{r.wrapperEl.style.scrollSnapType="",r._swiperImmediateVirtual=!1}))}else{if(!r.support.smoothScroll)return w({swiper:r,targetPosition:s,side:e?"left":"top"}),!0;h.scrollTo({[e?"left":"top"]:s,behavior:"smooth"})}return!0}return r.setTransition(t),r.setTranslate(v),r.updateActiveIndex(n),r.updateSlidesClasses(),r.emit("beforeTransitionStart",t,a),r.transitionStart(s,b),0===t?r.transitionEnd(s,b):r.animating||(r.animating=!0,r.onSlideToWrapperTransitionEnd||(r.onSlideToWrapperTransitionEnd=function(e){r&&!r.destroyed&&e.target===this&&(r.$wrapperEl[0].removeEventListener("transitionend",r.onSlideToWrapperTransitionEnd),r.$wrapperEl[0].removeEventListener("webkitTransitionEnd",r.onSlideToWrapperTransitionEnd),r.onSlideToWrapperTransitionEnd=null,delete r.onSlideToWrapperTransitionEnd,r.transitionEnd(s,b))}),r.$wrapperEl[0].addEventListener("transitionend",r.onSlideToWrapperTransitionEnd),r.$wrapperEl[0].addEventListener("webkitTransitionEnd",r.onSlideToWrapperTransitionEnd)),!0},slideToLoop:function(e,t,s,a){if(void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===s&&(s=!0),"string"==typeof e){const t=parseInt(e,10);if(!isFinite(t))throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${e}] given.`);e=t}const i=this;let r=e;return i.params.loop&&(r+=i.loopedSlides),i.slideTo(r,t,s,a)},slideNext:function(e,t,s){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0);const a=this,{animating:i,enabled:r,params:n}=a;if(!r)return a;let l=n.slidesPerGroup;"auto"===n.slidesPerView&&1===n.slidesPerGroup&&n.slidesPerGroupAuto&&(l=Math.max(a.slidesPerViewDynamic("current",!0),1));const o=a.activeIndexc(e)));let h=n[u.indexOf(p)-1];if(void 0===h&&i.cssMode){let e;n.forEach(((t,s)=>{p>=t&&(e=s)})),void 0!==e&&(h=n[e>0?e-1:e])}let m=0;if(void 0!==h&&(m=l.indexOf(h),m<0&&(m=a.activeIndex-1),"auto"===i.slidesPerView&&1===i.slidesPerGroup&&i.slidesPerGroupAuto&&(m=m-a.slidesPerViewDynamic("previous",!0)+1,m=Math.max(m,0))),i.rewind&&a.isBeginning){const i=a.params.virtual&&a.params.virtual.enabled&&a.virtual?a.virtual.slides.length-1:a.slides.length-1;return a.slideTo(i,e,t,s)}return a.slideTo(m,e,t,s)},slideReset:function(e,t,s){return void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),this.slideTo(this.activeIndex,e,t,s)},slideToClosest:function(e,t,s,a){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),void 0===a&&(a=.5);const i=this;let r=i.activeIndex;const n=Math.min(i.params.slidesPerGroupSkip,r),l=n+Math.floor((r-n)/i.params.slidesPerGroup),o=i.rtlTranslate?i.translate:-i.translate;if(o>=i.snapGrid[l]){const e=i.snapGrid[l];o-e>(i.snapGrid[l+1]-e)*a&&(r+=i.params.slidesPerGroup)}else{const e=i.snapGrid[l-1];o-e<=(i.snapGrid[l]-e)*a&&(r-=i.params.slidesPerGroup)}return r=Math.max(r,0),r=Math.min(r,i.slidesGrid.length-1),i.slideTo(r,e,t,s)},slideToClickedSlide:function(){const e=this,{params:t,$wrapperEl:s}=e,a="auto"===t.slidesPerView?e.slidesPerViewDynamic():t.slidesPerView;let i,r=e.clickedIndex;if(t.loop){if(e.animating)return;i=parseInt(d(e.clickedSlide).attr("data-swiper-slide-index"),10),t.centeredSlides?re.slides.length-e.loopedSlides+a/2?(e.loopFix(),r=s.children(`.${t.slideClass}[data-swiper-slide-index="${i}"]:not(.${t.slideDuplicateClass})`).eq(0).index(),p((()=>{e.slideTo(r)}))):e.slideTo(r):r>e.slides.length-a?(e.loopFix(),r=s.children(`.${t.slideClass}[data-swiper-slide-index="${i}"]:not(.${t.slideDuplicateClass})`).eq(0).index(),p((()=>{e.slideTo(r)}))):e.slideTo(r)}else e.slideTo(r)}};var z={loopCreate:function(){const e=this,t=a(),{params:s,$wrapperEl:i}=e,r=i.children().length>0?d(i.children()[0].parentNode):i;r.children(`.${s.slideClass}.${s.slideDuplicateClass}`).remove();let n=r.children(`.${s.slideClass}`);if(s.loopFillGroupWithBlank){const e=s.slidesPerGroup-n.length%s.slidesPerGroup;if(e!==s.slidesPerGroup){for(let a=0;an.length&&e.params.loopedSlidesLimit&&(e.loopedSlides=n.length);const l=[],o=[];n.each(((e,t)=>{d(e).attr("data-swiper-slide-index",t)}));for(let t=0;t=0;e-=1)r.prepend(d(l[e].cloneNode(!0)).addClass(s.slideDuplicateClass))},loopFix:function(){const e=this;e.emit("beforeLoopFix");const{activeIndex:t,slides:s,loopedSlides:a,allowSlidePrev:i,allowSlideNext:r,snapGrid:n,rtlTranslate:l}=e;let o;e.allowSlidePrev=!0,e.allowSlideNext=!0;const d=-n[t]-e.getTranslate();if(t=s.length-a){o=-s.length+t+a,o+=a;e.slideTo(o,0,!1,!0)&&0!==d&&e.setTranslate((l?-e.translate:e.translate)-d)}e.allowSlidePrev=i,e.allowSlideNext=r,e.emit("loopFix")},loopDestroy:function(){const{$wrapperEl:e,params:t,slides:s}=this;e.children(`.${t.slideClass}.${t.slideDuplicateClass},.${t.slideClass}.${t.slideBlankClass}`).remove(),s.removeAttr("data-swiper-slide-index")}};function L(e){const t=this,s=a(),i=r(),n=t.touchEventsData,{params:l,touches:o,enabled:c}=t;if(!c)return;if(t.animating&&l.preventInteractionOnTransition)return;!t.animating&&l.cssMode&&l.loop&&t.loopFix();let p=e;p.originalEvent&&(p=p.originalEvent);let h=d(p.target);if("wrapper"===l.touchEventsTarget&&!h.closest(t.wrapperEl).length)return;if(n.isTouchEvent="touchstart"===p.type,!n.isTouchEvent&&"which"in p&&3===p.which)return;if(!n.isTouchEvent&&"button"in p&&p.button>0)return;if(n.isTouched&&n.isMoved)return;const m=!!l.noSwipingClass&&""!==l.noSwipingClass,f=e.composedPath?e.composedPath():e.path;m&&p.target&&p.target.shadowRoot&&f&&(h=d(f[0]));const g=l.noSwipingSelector?l.noSwipingSelector:`.${l.noSwipingClass}`,v=!(!p.target||!p.target.shadowRoot);if(l.noSwiping&&(v?function(e,t){return void 0===t&&(t=this),function t(s){if(!s||s===a()||s===r())return null;s.assignedSlot&&(s=s.assignedSlot);const i=s.closest(e);return i||s.getRootNode?i||t(s.getRootNode().host):null}(t)}(g,h[0]):h.closest(g)[0]))return void(t.allowClick=!0);if(l.swipeHandler&&!h.closest(l.swipeHandler)[0])return;o.currentX="touchstart"===p.type?p.targetTouches[0].pageX:p.pageX,o.currentY="touchstart"===p.type?p.targetTouches[0].pageY:p.pageY;const w=o.currentX,b=o.currentY,x=l.edgeSwipeDetection||l.iOSEdgeSwipeDetection,y=l.edgeSwipeThreshold||l.iOSEdgeSwipeThreshold;if(x&&(w<=y||w>=i.innerWidth-y)){if("prevent"!==x)return;e.preventDefault()}if(Object.assign(n,{isTouched:!0,isMoved:!1,allowTouchCallbacks:!0,isScrolling:void 0,startMoving:void 0}),o.startX=w,o.startY=b,n.touchStartTime=u(),t.allowClick=!0,t.updateSize(),t.swipeDirection=void 0,l.threshold>0&&(n.allowThresholdMove=!1),"touchstart"!==p.type){let e=!0;h.is(n.focusableElements)&&(e=!1,"SELECT"===h[0].nodeName&&(n.isTouched=!1)),s.activeElement&&d(s.activeElement).is(n.focusableElements)&&s.activeElement!==h[0]&&s.activeElement.blur();const a=e&&t.allowTouchMove&&l.touchStartPreventDefault;!l.touchStartForcePreventDefault&&!a||h[0].isContentEditable||p.preventDefault()}t.params.freeMode&&t.params.freeMode.enabled&&t.freeMode&&t.animating&&!l.cssMode&&t.freeMode.onTouchStart(),t.emit("touchStart",p)}function O(e){const t=a(),s=this,i=s.touchEventsData,{params:r,touches:n,rtlTranslate:l,enabled:o}=s;if(!o)return;let c=e;if(c.originalEvent&&(c=c.originalEvent),!i.isTouched)return void(i.startMoving&&i.isScrolling&&s.emit("touchMoveOpposite",c));if(i.isTouchEvent&&"touchmove"!==c.type)return;const p="touchmove"===c.type&&c.targetTouches&&(c.targetTouches[0]||c.changedTouches[0]),h="touchmove"===c.type?p.pageX:c.pageX,m="touchmove"===c.type?p.pageY:c.pageY;if(c.preventedByNestedSwiper)return n.startX=h,void(n.startY=m);if(!s.allowTouchMove)return d(c.target).is(i.focusableElements)||(s.allowClick=!1),void(i.isTouched&&(Object.assign(n,{startX:h,startY:m,currentX:h,currentY:m}),i.touchStartTime=u()));if(i.isTouchEvent&&r.touchReleaseOnEdges&&!r.loop)if(s.isVertical()){if(mn.startY&&s.translate>=s.minTranslate())return i.isTouched=!1,void(i.isMoved=!1)}else if(hn.startX&&s.translate>=s.minTranslate())return;if(i.isTouchEvent&&t.activeElement&&c.target===t.activeElement&&d(c.target).is(i.focusableElements))return i.isMoved=!0,void(s.allowClick=!1);if(i.allowTouchCallbacks&&s.emit("touchMove",c),c.targetTouches&&c.targetTouches.length>1)return;n.currentX=h,n.currentY=m;const f=n.currentX-n.startX,g=n.currentY-n.startY;if(s.params.threshold&&Math.sqrt(f**2+g**2)=25&&(e=180*Math.atan2(Math.abs(g),Math.abs(f))/Math.PI,i.isScrolling=s.isHorizontal()?e>r.touchAngle:90-e>r.touchAngle)}if(i.isScrolling&&s.emit("touchMoveOpposite",c),void 0===i.startMoving&&(n.currentX===n.startX&&n.currentY===n.startY||(i.startMoving=!0)),i.isScrolling)return void(i.isTouched=!1);if(!i.startMoving)return;s.allowClick=!1,!r.cssMode&&c.cancelable&&c.preventDefault(),r.touchMoveStopPropagation&&!r.nested&&c.stopPropagation(),i.isMoved||(r.loop&&!r.cssMode&&s.loopFix(),i.startTranslate=s.getTranslate(),s.setTransition(0),s.animating&&s.$wrapperEl.trigger("webkitTransitionEnd transitionend"),i.allowMomentumBounce=!1,!r.grabCursor||!0!==s.allowSlideNext&&!0!==s.allowSlidePrev||s.setGrabCursor(!0),s.emit("sliderFirstMove",c)),s.emit("sliderMove",c),i.isMoved=!0;let v=s.isHorizontal()?f:g;n.diff=v,v*=r.touchRatio,l&&(v=-v),s.swipeDirection=v>0?"prev":"next",i.currentTranslate=v+i.startTranslate;let w=!0,b=r.resistanceRatio;if(r.touchReleaseOnEdges&&(b=0),v>0&&i.currentTranslate>s.minTranslate()?(w=!1,r.resistance&&(i.currentTranslate=s.minTranslate()-1+(-s.minTranslate()+i.startTranslate+v)**b)):v<0&&i.currentTranslatei.startTranslate&&(i.currentTranslate=i.startTranslate),s.allowSlidePrev||s.allowSlideNext||(i.currentTranslate=i.startTranslate),r.threshold>0){if(!(Math.abs(v)>r.threshold||i.allowThresholdMove))return void(i.currentTranslate=i.startTranslate);if(!i.allowThresholdMove)return i.allowThresholdMove=!0,n.startX=n.currentX,n.startY=n.currentY,i.currentTranslate=i.startTranslate,void(n.diff=s.isHorizontal()?n.currentX-n.startX:n.currentY-n.startY)}r.followFinger&&!r.cssMode&&((r.freeMode&&r.freeMode.enabled&&s.freeMode||r.watchSlidesProgress)&&(s.updateActiveIndex(),s.updateSlidesClasses()),s.params.freeMode&&r.freeMode.enabled&&s.freeMode&&s.freeMode.onTouchMove(),s.updateProgress(i.currentTranslate),s.setTranslate(i.currentTranslate))}function I(e){const t=this,s=t.touchEventsData,{params:a,touches:i,rtlTranslate:r,slidesGrid:n,enabled:l}=t;if(!l)return;let o=e;if(o.originalEvent&&(o=o.originalEvent),s.allowTouchCallbacks&&t.emit("touchEnd",o),s.allowTouchCallbacks=!1,!s.isTouched)return s.isMoved&&a.grabCursor&&t.setGrabCursor(!1),s.isMoved=!1,void(s.startMoving=!1);a.grabCursor&&s.isMoved&&s.isTouched&&(!0===t.allowSlideNext||!0===t.allowSlidePrev)&&t.setGrabCursor(!1);const d=u(),c=d-s.touchStartTime;if(t.allowClick){const e=o.path||o.composedPath&&o.composedPath();t.updateClickedSlide(e&&e[0]||o.target),t.emit("tap click",o),c<300&&d-s.lastClickTime<300&&t.emit("doubleTap doubleClick",o)}if(s.lastClickTime=u(),p((()=>{t.destroyed||(t.allowClick=!0)})),!s.isTouched||!s.isMoved||!t.swipeDirection||0===i.diff||s.currentTranslate===s.startTranslate)return s.isTouched=!1,s.isMoved=!1,void(s.startMoving=!1);let h;if(s.isTouched=!1,s.isMoved=!1,s.startMoving=!1,h=a.followFinger?r?t.translate:-t.translate:-s.currentTranslate,a.cssMode)return;if(t.params.freeMode&&a.freeMode.enabled)return void t.freeMode.onTouchEnd({currentPos:h});let m=0,f=t.slidesSizesGrid[0];for(let e=0;e=n[e]&&h=n[e]&&(m=e,f=n[n.length-1]-n[n.length-2])}let g=null,v=null;a.rewind&&(t.isBeginning?v=t.params.virtual&&t.params.virtual.enabled&&t.virtual?t.virtual.slides.length-1:t.slides.length-1:t.isEnd&&(g=0));const w=(h-n[m])/f,b=ma.longSwipesMs){if(!a.longSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&(w>=a.longSwipesRatio?t.slideTo(a.rewind&&t.isEnd?g:m+b):t.slideTo(m)),"prev"===t.swipeDirection&&(w>1-a.longSwipesRatio?t.slideTo(m+b):null!==v&&w<0&&Math.abs(w)>a.longSwipesRatio?t.slideTo(v):t.slideTo(m))}else{if(!a.shortSwipes)return void t.slideTo(t.activeIndex);t.navigation&&(o.target===t.navigation.nextEl||o.target===t.navigation.prevEl)?o.target===t.navigation.nextEl?t.slideTo(m+b):t.slideTo(m):("next"===t.swipeDirection&&t.slideTo(null!==g?g:m+b),"prev"===t.swipeDirection&&t.slideTo(null!==v?v:m))}}function A(){const e=this,{params:t,el:s}=e;if(s&&0===s.offsetWidth)return;t.breakpoints&&e.setBreakpoint();const{allowSlideNext:a,allowSlidePrev:i,snapGrid:r}=e;e.allowSlideNext=!0,e.allowSlidePrev=!0,e.updateSize(),e.updateSlides(),e.updateSlidesClasses(),("auto"===t.slidesPerView||t.slidesPerView>1)&&e.isEnd&&!e.isBeginning&&!e.params.centeredSlides?e.slideTo(e.slides.length-1,0,!1,!0):e.slideTo(e.activeIndex,0,!1,!0),e.autoplay&&e.autoplay.running&&e.autoplay.paused&&e.autoplay.run(),e.allowSlidePrev=i,e.allowSlideNext=a,e.params.watchOverflow&&r!==e.snapGrid&&e.checkOverflow()}function D(e){const t=this;t.enabled&&(t.allowClick||(t.params.preventClicks&&e.preventDefault(),t.params.preventClicksPropagation&&t.animating&&(e.stopPropagation(),e.stopImmediatePropagation())))}function G(){const e=this,{wrapperEl:t,rtlTranslate:s,enabled:a}=e;if(!a)return;let i;e.previousTranslate=e.translate,e.isHorizontal()?e.translate=-t.scrollLeft:e.translate=-t.scrollTop,0===e.translate&&(e.translate=0),e.updateActiveIndex(),e.updateSlidesClasses();const r=e.maxTranslate()-e.minTranslate();i=0===r?0:(e.translate-e.minTranslate())/r,i!==e.progress&&e.updateProgress(s?-e.translate:e.translate),e.emit("setTranslate",e.translate,!1)}let N=!1;function B(){}const H=(e,t)=>{const s=a(),{params:i,touchEvents:r,el:n,wrapperEl:l,device:o,support:d}=e,c=!!i.nested,p="on"===t?"addEventListener":"removeEventListener",u=t;if(d.touch){const t=!("touchstart"!==r.start||!d.passiveListener||!i.passiveListeners)&&{passive:!0,capture:!1};n[p](r.start,e.onTouchStart,t),n[p](r.move,e.onTouchMove,d.passiveListener?{passive:!1,capture:c}:c),n[p](r.end,e.onTouchEnd,t),r.cancel&&n[p](r.cancel,e.onTouchEnd,t)}else n[p](r.start,e.onTouchStart,!1),s[p](r.move,e.onTouchMove,c),s[p](r.end,e.onTouchEnd,!1);(i.preventClicks||i.preventClicksPropagation)&&n[p]("click",e.onClick,!0),i.cssMode&&l[p]("scroll",e.onScroll),i.updateOnWindowResize?e[u](o.ios||o.android?"resize orientationchange observerUpdate":"resize observerUpdate",A,!0):e[u]("observerUpdate",A,!0)};var X={attachEvents:function(){const e=this,t=a(),{params:s,support:i}=e;e.onTouchStart=L.bind(e),e.onTouchMove=O.bind(e),e.onTouchEnd=I.bind(e),s.cssMode&&(e.onScroll=G.bind(e)),e.onClick=D.bind(e),i.touch&&!N&&(t.addEventListener("touchstart",B),N=!0),H(e,"on")},detachEvents:function(){H(this,"off")}};const Y=(e,t)=>e.grid&&t.grid&&t.grid.rows>1;var R={addClasses:function(){const e=this,{classNames:t,params:s,rtl:a,$el:i,device:r,support:n}=e,l=function(e,t){const s=[];return e.forEach((e=>{"object"==typeof e?Object.keys(e).forEach((a=>{e[a]&&s.push(t+a)})):"string"==typeof e&&s.push(t+e)})),s}(["initialized",s.direction,{"pointer-events":!n.touch},{"free-mode":e.params.freeMode&&s.freeMode.enabled},{autoheight:s.autoHeight},{rtl:a},{grid:s.grid&&s.grid.rows>1},{"grid-column":s.grid&&s.grid.rows>1&&"column"===s.grid.fill},{android:r.android},{ios:r.ios},{"css-mode":s.cssMode},{centered:s.cssMode&&s.centeredSlides},{"watch-progress":s.watchSlidesProgress}],s.containerModifierClass);t.push(...l),i.addClass([...t].join(" ")),e.emitContainerClasses()},removeClasses:function(){const{$el:e,classNames:t}=this;e.removeClass(t.join(" ")),this.emitContainerClasses()}};var W={init:!0,direction:"horizontal",touchEventsTarget:"wrapper",initialSlide:0,speed:300,cssMode:!1,updateOnWindowResize:!0,resizeObserver:!0,nested:!1,createElements:!1,enabled:!0,focusableElements:"input, select, option, textarea, button, video, label",width:null,height:null,preventInteractionOnTransition:!1,userAgent:null,url:null,edgeSwipeDetection:!1,edgeSwipeThreshold:20,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",breakpoints:void 0,breakpointsBase:"window",spaceBetween:0,slidesPerView:1,slidesPerGroup:1,slidesPerGroupSkip:0,slidesPerGroupAuto:!1,centeredSlides:!1,centeredSlidesBounds:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,normalizeSlideIndex:!0,centerInsufficientSlides:!1,watchOverflow:!0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,allowTouchMove:!0,threshold:0,touchMoveStopPropagation:!1,touchStartPreventDefault:!0,touchStartForcePreventDefault:!1,touchReleaseOnEdges:!1,uniqueNavElements:!0,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,loopedSlidesLimit:!0,loopFillGroupWithBlank:!1,loopPreventsSlide:!0,rewind:!1,allowSlidePrev:!0,allowSlideNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",noSwipingSelector:null,passiveListeners:!0,maxBackfaceHiddenSlides:10,containerModifierClass:"swiper-",slideClass:"swiper-slide",slideBlankClass:"swiper-slide-invisible-blank",slideActiveClass:"swiper-slide-active",slideDuplicateActiveClass:"swiper-slide-duplicate-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slideDuplicateNextClass:"swiper-slide-duplicate-next",slidePrevClass:"swiper-slide-prev",slideDuplicatePrevClass:"swiper-slide-duplicate-prev",wrapperClass:"swiper-wrapper",runCallbacksOnInit:!0,_emitClasses:!1};function q(e,t){return function(s){void 0===s&&(s={});const a=Object.keys(s)[0],i=s[a];"object"==typeof i&&null!==i?(["navigation","pagination","scrollbar"].indexOf(a)>=0&&!0===e[a]&&(e[a]={auto:!0}),a in e&&"enabled"in i?(!0===e[a]&&(e[a]={enabled:!0}),"object"!=typeof e[a]||"enabled"in e[a]||(e[a].enabled=!0),e[a]||(e[a]={enabled:!1}),g(t,s)):g(t,s)):g(t,s)}}const j={eventsEmitter:$,update:S,translate:M,transition:{setTransition:function(e,t){const s=this;s.params.cssMode||s.$wrapperEl.transition(e),s.emit("setTransition",e,t)},transitionStart:function(e,t){void 0===e&&(e=!0);const s=this,{params:a}=s;a.cssMode||(a.autoHeight&&s.updateAutoHeight(),P({swiper:s,runCallbacks:e,direction:t,step:"Start"}))},transitionEnd:function(e,t){void 0===e&&(e=!0);const s=this,{params:a}=s;s.animating=!1,a.cssMode||(s.setTransition(0),P({swiper:s,runCallbacks:e,direction:t,step:"End"}))}},slide:k,loop:z,grabCursor:{setGrabCursor:function(e){const t=this;if(t.support.touch||!t.params.simulateTouch||t.params.watchOverflow&&t.isLocked||t.params.cssMode)return;const s="container"===t.params.touchEventsTarget?t.el:t.wrapperEl;s.style.cursor="move",s.style.cursor=e?"grabbing":"grab"},unsetGrabCursor:function(){const e=this;e.support.touch||e.params.watchOverflow&&e.isLocked||e.params.cssMode||(e["container"===e.params.touchEventsTarget?"el":"wrapperEl"].style.cursor="")}},events:X,breakpoints:{setBreakpoint:function(){const e=this,{activeIndex:t,initialized:s,loopedSlides:a=0,params:i,$el:r}=e,n=i.breakpoints;if(!n||n&&0===Object.keys(n).length)return;const l=e.getBreakpoint(n,e.params.breakpointsBase,e.el);if(!l||e.currentBreakpoint===l)return;const o=(l in n?n[l]:void 0)||e.originalParams,d=Y(e,i),c=Y(e,o),p=i.enabled;d&&!c?(r.removeClass(`${i.containerModifierClass}grid ${i.containerModifierClass}grid-column`),e.emitContainerClasses()):!d&&c&&(r.addClass(`${i.containerModifierClass}grid`),(o.grid.fill&&"column"===o.grid.fill||!o.grid.fill&&"column"===i.grid.fill)&&r.addClass(`${i.containerModifierClass}grid-column`),e.emitContainerClasses()),["navigation","pagination","scrollbar"].forEach((t=>{const s=i[t]&&i[t].enabled,a=o[t]&&o[t].enabled;s&&!a&&e[t].disable(),!s&&a&&e[t].enable()}));const u=o.direction&&o.direction!==i.direction,h=i.loop&&(o.slidesPerView!==i.slidesPerView||u);u&&s&&e.changeDirection(),g(e.params,o);const m=e.params.enabled;Object.assign(e,{allowTouchMove:e.params.allowTouchMove,allowSlideNext:e.params.allowSlideNext,allowSlidePrev:e.params.allowSlidePrev}),p&&!m?e.disable():!p&&m&&e.enable(),e.currentBreakpoint=l,e.emit("_beforeBreakpoint",o),h&&s&&(e.loopDestroy(),e.loopCreate(),e.updateSlides(),e.slideTo(t-a+e.loopedSlides,0,!1)),e.emit("breakpoint",o)},getBreakpoint:function(e,t,s){if(void 0===t&&(t="window"),!e||"container"===t&&!s)return;let a=!1;const i=r(),n="window"===t?i.innerHeight:s.clientHeight,l=Object.keys(e).map((e=>{if("string"==typeof e&&0===e.indexOf("@")){const t=parseFloat(e.substr(1));return{value:n*t,point:e}}return{value:e,point:e}}));l.sort(((e,t)=>parseInt(e.value,10)-parseInt(t.value,10)));for(let e=0;es}else e.isLocked=1===e.snapGrid.length;!0===s.allowSlideNext&&(e.allowSlideNext=!e.isLocked),!0===s.allowSlidePrev&&(e.allowSlidePrev=!e.isLocked),t&&t!==e.isLocked&&(e.isEnd=!1),t!==e.isLocked&&e.emit(e.isLocked?"lock":"unlock")}},classes:R,images:{loadImage:function(e,t,s,a,i,n){const l=r();let o;function c(){n&&n()}d(e).parent("picture")[0]||e.complete&&i?c():t?(o=new l.Image,o.onload=c,o.onerror=c,a&&(o.sizes=a),s&&(o.srcset=s),t&&(o.src=t)):c()},preloadImages:function(){const e=this;function t(){null!=e&&e&&!e.destroyed&&(void 0!==e.imagesLoaded&&(e.imagesLoaded+=1),e.imagesLoaded===e.imagesToLoad.length&&(e.params.updateOnImagesReady&&e.update(),e.emit("imagesReady")))}e.imagesToLoad=e.$el.find("img");for(let s=0;s1){const e=[];return d(t.el).each((s=>{const a=g({},t,{el:s});e.push(new V(a))})),e}const r=this;r.__swiper__=!0,r.support=E(),r.device=C({userAgent:t.userAgent}),r.browser=T(),r.eventsListeners={},r.eventsAnyListeners=[],r.modules=[...r.__modules__],t.modules&&Array.isArray(t.modules)&&r.modules.push(...t.modules);const n={};r.modules.forEach((e=>{e({swiper:r,extendParams:q(t,n),on:r.on.bind(r),once:r.once.bind(r),off:r.off.bind(r),emit:r.emit.bind(r)})}));const l=g({},W,n);return r.params=g({},l,_,t),r.originalParams=g({},r.params),r.passedParams=g({},t),r.params&&r.params.on&&Object.keys(r.params.on).forEach((e=>{r.on(e,r.params.on[e])})),r.params&&r.params.onAny&&r.onAny(r.params.onAny),r.$=d,Object.assign(r,{enabled:r.params.enabled,el:e,classNames:[],slides:d(),slidesGrid:[],snapGrid:[],slidesSizesGrid:[],isHorizontal:()=>"horizontal"===r.params.direction,isVertical:()=>"vertical"===r.params.direction,activeIndex:0,realIndex:0,isBeginning:!0,isEnd:!1,translate:0,previousTranslate:0,progress:0,velocity:0,animating:!1,allowSlideNext:r.params.allowSlideNext,allowSlidePrev:r.params.allowSlidePrev,touchEvents:function(){const e=["touchstart","touchmove","touchend","touchcancel"],t=["pointerdown","pointermove","pointerup"];return r.touchEventsTouch={start:e[0],move:e[1],end:e[2],cancel:e[3]},r.touchEventsDesktop={start:t[0],move:t[1],end:t[2]},r.support.touch||!r.params.simulateTouch?r.touchEventsTouch:r.touchEventsDesktop}(),touchEventsData:{isTouched:void 0,isMoved:void 0,allowTouchCallbacks:void 0,touchStartTime:void 0,isScrolling:void 0,currentTranslate:void 0,startTranslate:void 0,allowThresholdMove:void 0,focusableElements:r.params.focusableElements,lastClickTime:u(),clickTimeout:void 0,velocities:[],allowMomentumBounce:void 0,isTouchEvent:void 0,startMoving:void 0},allowClick:!0,allowTouchMove:r.params.allowTouchMove,touches:{startX:0,startY:0,currentX:0,currentY:0,diff:0},imagesToLoad:[],imagesLoaded:0}),r.emit("_swiper"),r.params.init&&r.init(),r}enable(){const e=this;e.enabled||(e.enabled=!0,e.params.grabCursor&&e.setGrabCursor(),e.emit("enable"))}disable(){const e=this;e.enabled&&(e.enabled=!1,e.params.grabCursor&&e.unsetGrabCursor(),e.emit("disable"))}setProgress(e,t){const s=this;e=Math.min(Math.max(e,0),1);const a=s.minTranslate(),i=(s.maxTranslate()-a)*e+a;s.translateTo(i,void 0===t?0:t),s.updateActiveIndex(),s.updateSlidesClasses()}emitContainerClasses(){const e=this;if(!e.params._emitClasses||!e.el)return;const t=e.el.className.split(" ").filter((t=>0===t.indexOf("swiper")||0===t.indexOf(e.params.containerModifierClass)));e.emit("_containerClasses",t.join(" "))}getSlideClasses(e){const t=this;return t.destroyed?"":e.className.split(" ").filter((e=>0===e.indexOf("swiper-slide")||0===e.indexOf(t.params.slideClass))).join(" ")}emitSlidesClasses(){const e=this;if(!e.params._emitClasses||!e.el)return;const t=[];e.slides.each((s=>{const a=e.getSlideClasses(s);t.push({slideEl:s,classNames:a}),e.emit("_slideClass",s,a)})),e.emit("_slideClasses",t)}slidesPerViewDynamic(e,t){void 0===e&&(e="current"),void 0===t&&(t=!1);const{params:s,slides:a,slidesGrid:i,slidesSizesGrid:r,size:n,activeIndex:l}=this;let o=1;if(s.centeredSlides){let e,t=a[l].swiperSlideSize;for(let s=l+1;sn&&(e=!0));for(let s=l-1;s>=0;s-=1)a[s]&&!e&&(t+=a[s].swiperSlideSize,o+=1,t>n&&(e=!0))}else if("current"===e)for(let e=l+1;e=0;e-=1){i[l]-i[e]1)&&e.isEnd&&!e.params.centeredSlides?e.slideTo(e.slides.length-1,0,!1,!0):e.slideTo(e.activeIndex,0,!1,!0),i||a()),s.watchOverflow&&t!==e.snapGrid&&e.checkOverflow(),e.emit("update")}changeDirection(e,t){void 0===t&&(t=!0);const s=this,a=s.params.direction;return e||(e="horizontal"===a?"vertical":"horizontal"),e===a||"horizontal"!==e&&"vertical"!==e||(s.$el.removeClass(`${s.params.containerModifierClass}${a}`).addClass(`${s.params.containerModifierClass}${e}`),s.emitContainerClasses(),s.params.direction=e,s.slides.each((t=>{"vertical"===e?t.style.width="":t.style.height=""})),s.emit("changeDirection"),t&&s.update()),s}changeLanguageDirection(e){const t=this;t.rtl&&"rtl"===e||!t.rtl&&"ltr"===e||(t.rtl="rtl"===e,t.rtlTranslate="horizontal"===t.params.direction&&t.rtl,t.rtl?(t.$el.addClass(`${t.params.containerModifierClass}rtl`),t.el.dir="rtl"):(t.$el.removeClass(`${t.params.containerModifierClass}rtl`),t.el.dir="ltr"),t.update())}mount(e){const t=this;if(t.mounted)return!0;const s=d(e||t.params.el);if(!(e=s[0]))return!1;e.swiper=t;const i=()=>`.${(t.params.wrapperClass||"").trim().split(" ").join(".")}`;let r=(()=>{if(e&&e.shadowRoot&&e.shadowRoot.querySelector){const t=d(e.shadowRoot.querySelector(i()));return t.children=e=>s.children(e),t}return s.children?s.children(i()):d(s).children(i())})();if(0===r.length&&t.params.createElements){const e=a().createElement("div");r=d(e),e.className=t.params.wrapperClass,s.append(e),s.children(`.${t.params.slideClass}`).each((e=>{r.append(e)}))}return Object.assign(t,{$el:s,el:e,$wrapperEl:r,wrapperEl:r[0],mounted:!0,rtl:"rtl"===e.dir.toLowerCase()||"rtl"===s.css("direction"),rtlTranslate:"horizontal"===t.params.direction&&("rtl"===e.dir.toLowerCase()||"rtl"===s.css("direction")),wrongRTL:"-webkit-box"===r.css("display")}),!0}init(e){const t=this;if(t.initialized)return t;return!1===t.mount(e)||(t.emit("beforeInit"),t.params.breakpoints&&t.setBreakpoint(),t.addClasses(),t.params.loop&&t.loopCreate(),t.updateSize(),t.updateSlides(),t.params.watchOverflow&&t.checkOverflow(),t.params.grabCursor&&t.enabled&&t.setGrabCursor(),t.params.preloadImages&&t.preloadImages(),t.params.loop?t.slideTo(t.params.initialSlide+t.loopedSlides,0,t.params.runCallbacksOnInit,!1,!0):t.slideTo(t.params.initialSlide,0,t.params.runCallbacksOnInit,!1,!0),t.attachEvents(),t.initialized=!0,t.emit("init"),t.emit("afterInit")),t}destroy(e,t){void 0===e&&(e=!0),void 0===t&&(t=!0);const s=this,{params:a,$el:i,$wrapperEl:r,slides:n}=s;return void 0===s.params||s.destroyed||(s.emit("beforeDestroy"),s.initialized=!1,s.detachEvents(),a.loop&&s.loopDestroy(),t&&(s.removeClasses(),i.removeAttr("style"),r.removeAttr("style"),n&&n.length&&n.removeClass([a.slideVisibleClass,a.slideActiveClass,a.slideNextClass,a.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-slide-index")),s.emit("destroy"),Object.keys(s.eventsListeners).forEach((e=>{s.off(e)})),!1!==e&&(s.$el[0].swiper=null,function(e){const t=e;Object.keys(t).forEach((e=>{try{t[e]=null}catch(e){}try{delete t[e]}catch(e){}}))}(s)),s.destroyed=!0),null}static extendDefaults(e){g(_,e)}static get extendedDefaults(){return _}static get defaults(){return W}static installModule(e){V.prototype.__modules__||(V.prototype.__modules__=[]);const t=V.prototype.__modules__;"function"==typeof e&&t.indexOf(e)<0&&t.push(e)}static use(e){return Array.isArray(e)?(e.forEach((e=>V.installModule(e))),V):(V.installModule(e),V)}}function F(e,t,s,i){const r=a();return e.params.createElements&&Object.keys(i).forEach((a=>{if(!s[a]&&!0===s.auto){let n=e.$el.children(`.${i[a]}`)[0];n||(n=r.createElement("div"),n.className=i[a],e.$el.append(n)),s[a]=n,t[a]=n}})),s}function U(e){return void 0===e&&(e=""),`.${e.trim().replace(/([\.:!\/])/g,"\\$1").replace(/ /g,".")}`}function K(e){const t=this,{$wrapperEl:s,params:a}=t;if(a.loop&&t.loopDestroy(),"object"==typeof e&&"length"in e)for(let t=0;t=l)return void s.appendSlide(t);let o=n>e?n+1:n;const d=[];for(let t=l-1;t>=e;t-=1){const e=s.slides.eq(t);e.remove(),d.unshift(e)}if("object"==typeof t&&"length"in t){for(let e=0;ee?n+t.length:n}else a.append(t);for(let e=0;e{if(s.params.effect!==t)return;s.classNames.push(`${s.params.containerModifierClass}${t}`),l&&l()&&s.classNames.push(`${s.params.containerModifierClass}3d`);const e=n?n():{};Object.assign(s.params,e),Object.assign(s.originalParams,e)})),a("setTranslate",(()=>{s.params.effect===t&&i()})),a("setTransition",((e,a)=>{s.params.effect===t&&r(a)})),a("transitionEnd",(()=>{if(s.params.effect===t&&o){if(!d||!d().slideShadows)return;s.slides.each((e=>{s.$(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").remove()})),o()}})),a("virtualUpdate",(()=>{s.params.effect===t&&(s.slides.length||(c=!0),requestAnimationFrame((()=>{c&&s.slides&&s.slides.length&&(i(),c=!1)})))}))}function se(e,t){return e.transformEl?t.find(e.transformEl).css({"backface-visibility":"hidden","-webkit-backface-visibility":"hidden"}):t}function ae(e){let{swiper:t,duration:s,transformEl:a,allSlides:i}=e;const{slides:r,activeIndex:n,$wrapperEl:l}=t;if(t.params.virtualTranslate&&0!==s){let e,s=!1;e=i?a?r.find(a):r:a?r.eq(n).find(a):r.eq(n),e.transitionEnd((()=>{if(s)return;if(!t||t.destroyed)return;s=!0,t.animating=!1;const e=["webkitTransitionEnd","transitionend"];for(let t=0;t`),i.append(r)),r}Object.keys(j).forEach((e=>{Object.keys(j[e]).forEach((t=>{V.prototype[t]=j[e][t]}))})),V.use([function(e){let{swiper:t,on:s,emit:a}=e;const i=r();let n=null,l=null;const o=()=>{t&&!t.destroyed&&t.initialized&&(a("beforeResize"),a("resize"))},d=()=>{t&&!t.destroyed&&t.initialized&&a("orientationchange")};s("init",(()=>{t.params.resizeObserver&&void 0!==i.ResizeObserver?t&&!t.destroyed&&t.initialized&&(n=new ResizeObserver((e=>{l=i.requestAnimationFrame((()=>{const{width:s,height:a}=t;let i=s,r=a;e.forEach((e=>{let{contentBoxSize:s,contentRect:a,target:n}=e;n&&n!==t.el||(i=a?a.width:(s[0]||s).inlineSize,r=a?a.height:(s[0]||s).blockSize)})),i===s&&r===a||o()}))})),n.observe(t.el)):(i.addEventListener("resize",o),i.addEventListener("orientationchange",d))})),s("destroy",(()=>{l&&i.cancelAnimationFrame(l),n&&n.unobserve&&t.el&&(n.unobserve(t.el),n=null),i.removeEventListener("resize",o),i.removeEventListener("orientationchange",d)}))},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const n=[],l=r(),o=function(e,t){void 0===t&&(t={});const s=new(l.MutationObserver||l.WebkitMutationObserver)((e=>{if(1===e.length)return void i("observerUpdate",e[0]);const t=function(){i("observerUpdate",e[0])};l.requestAnimationFrame?l.requestAnimationFrame(t):l.setTimeout(t,0)}));s.observe(e,{attributes:void 0===t.attributes||t.attributes,childList:void 0===t.childList||t.childList,characterData:void 0===t.characterData||t.characterData}),n.push(s)};s({observer:!1,observeParents:!1,observeSlideChildren:!1}),a("init",(()=>{if(t.params.observer){if(t.params.observeParents){const e=t.$el.parents();for(let t=0;t{n.forEach((e=>{e.disconnect()})),n.splice(0,n.length)}))}]);const re=[function(e){let t,{swiper:s,extendParams:a,on:i,emit:r}=e;function n(e,t){const a=s.params.virtual;if(a.cache&&s.virtual.cache[t])return s.virtual.cache[t];const i=a.renderSlide?d(a.renderSlide.call(s,e,t)):d(`
${e}
`);return i.attr("data-swiper-slide-index")||i.attr("data-swiper-slide-index",t),a.cache&&(s.virtual.cache[t]=i),i}function l(e){const{slidesPerView:t,slidesPerGroup:a,centeredSlides:i}=s.params,{addSlidesBefore:l,addSlidesAfter:o}=s.params.virtual,{from:d,to:c,slides:p,slidesGrid:u,offset:h}=s.virtual;s.params.cssMode||s.updateActiveIndex();const m=s.activeIndex||0;let f,g,v;f=s.rtlTranslate?"right":s.isHorizontal()?"left":"top",i?(g=Math.floor(t/2)+a+o,v=Math.floor(t/2)+a+l):(g=t+(a-1)+o,v=a+l);const w=Math.max((m||0)-v,0),b=Math.min((m||0)+g,p.length-1),x=(s.slidesGrid[w]||0)-(s.slidesGrid[0]||0);function y(){s.updateSlides(),s.updateProgress(),s.updateSlidesClasses(),s.lazy&&s.params.lazy.enabled&&s.lazy.load(),r("virtualUpdate")}if(Object.assign(s.virtual,{from:w,to:b,offset:x,slidesGrid:s.slidesGrid}),d===w&&c===b&&!e)return s.slidesGrid!==u&&x!==h&&s.slides.css(f,`${x}px`),s.updateProgress(),void r("virtualUpdate");if(s.params.virtual.renderExternal)return s.params.virtual.renderExternal.call(s,{offset:x,from:w,to:b,slides:function(){const e=[];for(let t=w;t<=b;t+=1)e.push(p[t]);return e}()}),void(s.params.virtual.renderExternalUpdate?y():r("virtualUpdate"));const E=[],C=[];if(e)s.$wrapperEl.find(`.${s.params.slideClass}`).remove();else for(let e=d;e<=c;e+=1)(eb)&&s.$wrapperEl.find(`.${s.params.slideClass}[data-swiper-slide-index="${e}"]`).remove();for(let t=0;t=w&&t<=b&&(void 0===c||e?C.push(t):(t>c&&C.push(t),t{s.$wrapperEl.append(n(p[e],e))})),E.sort(((e,t)=>t-e)).forEach((e=>{s.$wrapperEl.prepend(n(p[e],e))})),s.$wrapperEl.children(".swiper-slide").css(f,`${x}px`),y()}a({virtual:{enabled:!1,slides:[],cache:!0,renderSlide:null,renderExternal:null,renderExternalUpdate:!0,addSlidesBefore:0,addSlidesAfter:0}}),s.virtual={cache:{},from:void 0,to:void 0,slides:[],offset:0,slidesGrid:[]},i("beforeInit",(()=>{s.params.virtual.enabled&&(s.virtual.slides=s.params.virtual.slides,s.classNames.push(`${s.params.containerModifierClass}virtual`),s.params.watchSlidesProgress=!0,s.originalParams.watchSlidesProgress=!0,s.params.initialSlide||l())})),i("setTranslate",(()=>{s.params.virtual.enabled&&(s.params.cssMode&&!s._immediateVirtual?(clearTimeout(t),t=setTimeout((()=>{l()}),100)):l())})),i("init update resize",(()=>{s.params.virtual.enabled&&s.params.cssMode&&v(s.wrapperEl,"--swiper-virtual-size",`${s.virtualSize}px`)})),Object.assign(s.virtual,{appendSlide:function(e){if("object"==typeof e&&"length"in e)for(let t=0;t{const a=e[s],r=a.attr("data-swiper-slide-index");r&&a.attr("data-swiper-slide-index",parseInt(r,10)+i),t[parseInt(s,10)+i]=a})),s.virtual.cache=t}l(!0),s.slideTo(a,0)},removeSlide:function(e){if(null==e)return;let t=s.activeIndex;if(Array.isArray(e))for(let a=e.length-1;a>=0;a-=1)s.virtual.slides.splice(e[a],1),s.params.virtual.cache&&delete s.virtual.cache[e[a]],e[a]0&&0===t.$el.parents(`.${t.params.slideActiveClass}`).length)return;const a=t.$el,i=a[0].clientWidth,r=a[0].clientHeight,n=o.innerWidth,l=o.innerHeight,d=t.$el.offset();s&&(d.left-=t.$el[0].scrollLeft);const c=[[d.left,d.top],[d.left+i,d.top],[d.left,d.top+r],[d.left+i,d.top+r]];for(let t=0;t=0&&s[0]<=n&&s[1]>=0&&s[1]<=l){if(0===s[0]&&0===s[1])continue;e=!0}}if(!e)return}t.isHorizontal()?((d||c||p||u)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),((c||u)&&!s||(d||p)&&s)&&t.slideNext(),((d||p)&&!s||(c||u)&&s)&&t.slidePrev()):((d||c||h||m)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),(c||m)&&t.slideNext(),(d||h)&&t.slidePrev()),n("keyPress",i)}}function p(){t.keyboard.enabled||(d(l).on("keydown",c),t.keyboard.enabled=!0)}function u(){t.keyboard.enabled&&(d(l).off("keydown",c),t.keyboard.enabled=!1)}t.keyboard={enabled:!1},s({keyboard:{enabled:!1,onlyInViewport:!0,pageUpDown:!0}}),i("init",(()=>{t.params.keyboard.enabled&&p()})),i("destroy",(()=>{t.keyboard.enabled&&u()})),Object.assign(t.keyboard,{enable:p,disable:u})},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const n=r();let l;s({mousewheel:{enabled:!1,releaseOnEdges:!1,invert:!1,forceToAxis:!1,sensitivity:1,eventsTarget:"container",thresholdDelta:null,thresholdTime:null}}),t.mousewheel={enabled:!1};let o,c=u();const h=[];function m(){t.enabled&&(t.mouseEntered=!0)}function f(){t.enabled&&(t.mouseEntered=!1)}function g(e){return!(t.params.mousewheel.thresholdDelta&&e.delta=6&&u()-c<60||(e.direction<0?t.isEnd&&!t.params.loop||t.animating||(t.slideNext(),i("scroll",e.raw)):t.isBeginning&&!t.params.loop||t.animating||(t.slidePrev(),i("scroll",e.raw)),c=(new n.Date).getTime(),!1)))}function v(e){let s=e,a=!0;if(!t.enabled)return;const r=t.params.mousewheel;t.params.cssMode&&s.preventDefault();let n=t.$el;if("container"!==t.params.mousewheel.eventsTarget&&(n=d(t.params.mousewheel.eventsTarget)),!t.mouseEntered&&!n[0].contains(s.target)&&!r.releaseOnEdges)return!0;s.originalEvent&&(s=s.originalEvent);let c=0;const m=t.rtlTranslate?-1:1,f=function(e){let t=0,s=0,a=0,i=0;return"detail"in e&&(s=e.detail),"wheelDelta"in e&&(s=-e.wheelDelta/120),"wheelDeltaY"in e&&(s=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=s,s=0),a=10*t,i=10*s,"deltaY"in e&&(i=e.deltaY),"deltaX"in e&&(a=e.deltaX),e.shiftKey&&!a&&(a=i,i=0),(a||i)&&e.deltaMode&&(1===e.deltaMode?(a*=40,i*=40):(a*=800,i*=800)),a&&!t&&(t=a<1?-1:1),i&&!s&&(s=i<1?-1:1),{spinX:t,spinY:s,pixelX:a,pixelY:i}}(s);if(r.forceToAxis)if(t.isHorizontal()){if(!(Math.abs(f.pixelX)>Math.abs(f.pixelY)))return!0;c=-f.pixelX*m}else{if(!(Math.abs(f.pixelY)>Math.abs(f.pixelX)))return!0;c=-f.pixelY}else c=Math.abs(f.pixelX)>Math.abs(f.pixelY)?-f.pixelX*m:-f.pixelY;if(0===c)return!0;r.invert&&(c=-c);let v=t.getTranslate()+c*r.sensitivity;if(v>=t.minTranslate()&&(v=t.minTranslate()),v<=t.maxTranslate()&&(v=t.maxTranslate()),a=!!t.params.loop||!(v===t.minTranslate()||v===t.maxTranslate()),a&&t.params.nested&&s.stopPropagation(),t.params.freeMode&&t.params.freeMode.enabled){const e={time:u(),delta:Math.abs(c),direction:Math.sign(c)},a=o&&e.time=t.minTranslate()&&(n=t.minTranslate()),n<=t.maxTranslate()&&(n=t.maxTranslate()),t.setTransition(0),t.setTranslate(n),t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses(),(!d&&t.isBeginning||!u&&t.isEnd)&&t.updateSlidesClasses(),t.params.freeMode.sticky){clearTimeout(l),l=void 0,h.length>=15&&h.shift();const s=h.length?h[h.length-1]:void 0,a=h[0];if(h.push(e),s&&(e.delta>s.delta||e.direction!==s.direction))h.splice(0);else if(h.length>=15&&e.time-a.time<500&&a.delta-e.delta>=1&&e.delta<=6){const s=c>0?.8:.2;o=e,h.splice(0),l=p((()=>{t.slideToClosest(t.params.speed,!0,void 0,s)}),0)}l||(l=p((()=>{o=e,h.splice(0),t.slideToClosest(t.params.speed,!0,void 0,.5)}),500))}if(a||i("scroll",s),t.params.autoplay&&t.params.autoplayDisableOnInteraction&&t.autoplay.stop(),n===t.minTranslate()||n===t.maxTranslate())return!0}}else{const s={time:u(),delta:Math.abs(c),direction:Math.sign(c),raw:e};h.length>=2&&h.shift();const a=h.length?h[h.length-1]:void 0;if(h.push(s),a?(s.direction!==a.direction||s.delta>a.delta||s.time>a.time+150)&&g(s):g(s),function(e){const s=t.params.mousewheel;if(e.direction<0){if(t.isEnd&&!t.params.loop&&s.releaseOnEdges)return!0}else if(t.isBeginning&&!t.params.loop&&s.releaseOnEdges)return!0;return!1}(s))return!0}return s.preventDefault?s.preventDefault():s.returnValue=!1,!1}function w(e){let s=t.$el;"container"!==t.params.mousewheel.eventsTarget&&(s=d(t.params.mousewheel.eventsTarget)),s[e]("mouseenter",m),s[e]("mouseleave",f),s[e]("wheel",v)}function b(){return t.params.cssMode?(t.wrapperEl.removeEventListener("wheel",v),!0):!t.mousewheel.enabled&&(w("on"),t.mousewheel.enabled=!0,!0)}function x(){return t.params.cssMode?(t.wrapperEl.addEventListener(event,v),!0):!!t.mousewheel.enabled&&(w("off"),t.mousewheel.enabled=!1,!0)}a("init",(()=>{!t.params.mousewheel.enabled&&t.params.cssMode&&x(),t.params.mousewheel.enabled&&b()})),a("destroy",(()=>{t.params.cssMode&&b(),t.mousewheel.enabled&&x()})),Object.assign(t.mousewheel,{enable:b,disable:x})},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;function r(e){let s;return e&&(s=d(e),t.params.uniqueNavElements&&"string"==typeof e&&s.length>1&&1===t.$el.find(e).length&&(s=t.$el.find(e))),s}function n(e,s){const a=t.params.navigation;e&&e.length>0&&(e[s?"addClass":"removeClass"](a.disabledClass),e[0]&&"BUTTON"===e[0].tagName&&(e[0].disabled=s),t.params.watchOverflow&&t.enabled&&e[t.isLocked?"addClass":"removeClass"](a.lockClass))}function l(){if(t.params.loop)return;const{$nextEl:e,$prevEl:s}=t.navigation;n(s,t.isBeginning&&!t.params.rewind),n(e,t.isEnd&&!t.params.rewind)}function o(e){e.preventDefault(),(!t.isBeginning||t.params.loop||t.params.rewind)&&(t.slidePrev(),i("navigationPrev"))}function c(e){e.preventDefault(),(!t.isEnd||t.params.loop||t.params.rewind)&&(t.slideNext(),i("navigationNext"))}function p(){const e=t.params.navigation;if(t.params.navigation=F(t,t.originalParams.navigation,t.params.navigation,{nextEl:"swiper-button-next",prevEl:"swiper-button-prev"}),!e.nextEl&&!e.prevEl)return;const s=r(e.nextEl),a=r(e.prevEl);s&&s.length>0&&s.on("click",c),a&&a.length>0&&a.on("click",o),Object.assign(t.navigation,{$nextEl:s,nextEl:s&&s[0],$prevEl:a,prevEl:a&&a[0]}),t.enabled||(s&&s.addClass(e.lockClass),a&&a.addClass(e.lockClass))}function u(){const{$nextEl:e,$prevEl:s}=t.navigation;e&&e.length&&(e.off("click",c),e.removeClass(t.params.navigation.disabledClass)),s&&s.length&&(s.off("click",o),s.removeClass(t.params.navigation.disabledClass))}s({navigation:{nextEl:null,prevEl:null,hideOnClick:!1,disabledClass:"swiper-button-disabled",hiddenClass:"swiper-button-hidden",lockClass:"swiper-button-lock",navigationDisabledClass:"swiper-navigation-disabled"}}),t.navigation={nextEl:null,$nextEl:null,prevEl:null,$prevEl:null},a("init",(()=>{!1===t.params.navigation.enabled?h():(p(),l())})),a("toEdge fromEdge lock unlock",(()=>{l()})),a("destroy",(()=>{u()})),a("enable disable",(()=>{const{$nextEl:e,$prevEl:s}=t.navigation;e&&e[t.enabled?"removeClass":"addClass"](t.params.navigation.lockClass),s&&s[t.enabled?"removeClass":"addClass"](t.params.navigation.lockClass)})),a("click",((e,s)=>{const{$nextEl:a,$prevEl:r}=t.navigation,n=s.target;if(t.params.navigation.hideOnClick&&!d(n).is(r)&&!d(n).is(a)){if(t.pagination&&t.params.pagination&&t.params.pagination.clickable&&(t.pagination.el===n||t.pagination.el.contains(n)))return;let e;a?e=a.hasClass(t.params.navigation.hiddenClass):r&&(e=r.hasClass(t.params.navigation.hiddenClass)),i(!0===e?"navigationShow":"navigationHide"),a&&a.toggleClass(t.params.navigation.hiddenClass),r&&r.toggleClass(t.params.navigation.hiddenClass)}}));const h=()=>{t.$el.addClass(t.params.navigation.navigationDisabledClass),u()};Object.assign(t.navigation,{enable:()=>{t.$el.removeClass(t.params.navigation.navigationDisabledClass),p(),l()},disable:h,update:l,init:p,destroy:u})},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const r="swiper-pagination";let n;s({pagination:{el:null,bulletElement:"span",clickable:!1,hideOnClick:!1,renderBullet:null,renderProgressbar:null,renderFraction:null,renderCustom:null,progressbarOpposite:!1,type:"bullets",dynamicBullets:!1,dynamicMainBullets:1,formatFractionCurrent:e=>e,formatFractionTotal:e=>e,bulletClass:`${r}-bullet`,bulletActiveClass:`${r}-bullet-active`,modifierClass:`${r}-`,currentClass:`${r}-current`,totalClass:`${r}-total`,hiddenClass:`${r}-hidden`,progressbarFillClass:`${r}-progressbar-fill`,progressbarOppositeClass:`${r}-progressbar-opposite`,clickableClass:`${r}-clickable`,lockClass:`${r}-lock`,horizontalClass:`${r}-horizontal`,verticalClass:`${r}-vertical`,paginationDisabledClass:`${r}-disabled`}}),t.pagination={el:null,$el:null,bullets:[]};let l=0;function o(){return!t.params.pagination.el||!t.pagination.el||!t.pagination.$el||0===t.pagination.$el.length}function c(e,s){const{bulletActiveClass:a}=t.params.pagination;e[s]().addClass(`${a}-${s}`)[s]().addClass(`${a}-${s}-${s}`)}function p(){const e=t.rtl,s=t.params.pagination;if(o())return;const a=t.virtual&&t.params.virtual.enabled?t.virtual.slides.length:t.slides.length,r=t.pagination.$el;let p;const u=t.params.loop?Math.ceil((a-2*t.loopedSlides)/t.params.slidesPerGroup):t.snapGrid.length;if(t.params.loop?(p=Math.ceil((t.activeIndex-t.loopedSlides)/t.params.slidesPerGroup),p>a-1-2*t.loopedSlides&&(p-=a-2*t.loopedSlides),p>u-1&&(p-=u),p<0&&"bullets"!==t.params.paginationType&&(p=u+p)):p=void 0!==t.snapIndex?t.snapIndex:t.activeIndex||0,"bullets"===s.type&&t.pagination.bullets&&t.pagination.bullets.length>0){const a=t.pagination.bullets;let i,o,u;if(s.dynamicBullets&&(n=a.eq(0)[t.isHorizontal()?"outerWidth":"outerHeight"](!0),r.css(t.isHorizontal()?"width":"height",n*(s.dynamicMainBullets+4)+"px"),s.dynamicMainBullets>1&&void 0!==t.previousIndex&&(l+=p-(t.previousIndex-t.loopedSlides||0),l>s.dynamicMainBullets-1?l=s.dynamicMainBullets-1:l<0&&(l=0)),i=Math.max(p-l,0),o=i+(Math.min(a.length,s.dynamicMainBullets)-1),u=(o+i)/2),a.removeClass(["","-next","-next-next","-prev","-prev-prev","-main"].map((e=>`${s.bulletActiveClass}${e}`)).join(" ")),r.length>1)a.each((e=>{const t=d(e),a=t.index();a===p&&t.addClass(s.bulletActiveClass),s.dynamicBullets&&(a>=i&&a<=o&&t.addClass(`${s.bulletActiveClass}-main`),a===i&&c(t,"prev"),a===o&&c(t,"next"))}));else{const e=a.eq(p),r=e.index();if(e.addClass(s.bulletActiveClass),s.dynamicBullets){const e=a.eq(i),n=a.eq(o);for(let e=i;e<=o;e+=1)a.eq(e).addClass(`${s.bulletActiveClass}-main`);if(t.params.loop)if(r>=a.length){for(let e=s.dynamicMainBullets;e>=0;e-=1)a.eq(a.length-e).addClass(`${s.bulletActiveClass}-main`);a.eq(a.length-s.dynamicMainBullets-1).addClass(`${s.bulletActiveClass}-prev`)}else c(e,"prev"),c(n,"next");else c(e,"prev"),c(n,"next")}}if(s.dynamicBullets){const i=Math.min(a.length,s.dynamicMainBullets+4),r=(n*i-n)/2-u*n,l=e?"right":"left";a.css(t.isHorizontal()?l:"top",`${r}px`)}}if("fraction"===s.type&&(r.find(U(s.currentClass)).text(s.formatFractionCurrent(p+1)),r.find(U(s.totalClass)).text(s.formatFractionTotal(u))),"progressbar"===s.type){let e;e=s.progressbarOpposite?t.isHorizontal()?"vertical":"horizontal":t.isHorizontal()?"horizontal":"vertical";const a=(p+1)/u;let i=1,n=1;"horizontal"===e?i=a:n=a,r.find(U(s.progressbarFillClass)).transform(`translate3d(0,0,0) scaleX(${i}) scaleY(${n})`).transition(t.params.speed)}"custom"===s.type&&s.renderCustom?(r.html(s.renderCustom(t,p+1,u)),i("paginationRender",r[0])):i("paginationUpdate",r[0]),t.params.watchOverflow&&t.enabled&&r[t.isLocked?"addClass":"removeClass"](s.lockClass)}function u(){const e=t.params.pagination;if(o())return;const s=t.virtual&&t.params.virtual.enabled?t.virtual.slides.length:t.slides.length,a=t.pagination.$el;let r="";if("bullets"===e.type){let i=t.params.loop?Math.ceil((s-2*t.loopedSlides)/t.params.slidesPerGroup):t.snapGrid.length;t.params.freeMode&&t.params.freeMode.enabled&&!t.params.loop&&i>s&&(i=s);for(let s=0;s`;a.html(r),t.pagination.bullets=a.find(U(e.bulletClass))}"fraction"===e.type&&(r=e.renderFraction?e.renderFraction.call(t,e.currentClass,e.totalClass):` / `,a.html(r)),"progressbar"===e.type&&(r=e.renderProgressbar?e.renderProgressbar.call(t,e.progressbarFillClass):``,a.html(r)),"custom"!==e.type&&i("paginationRender",t.pagination.$el[0])}function h(){t.params.pagination=F(t,t.originalParams.pagination,t.params.pagination,{el:"swiper-pagination"});const e=t.params.pagination;if(!e.el)return;let s=d(e.el);0!==s.length&&(t.params.uniqueNavElements&&"string"==typeof e.el&&s.length>1&&(s=t.$el.find(e.el),s.length>1&&(s=s.filter((e=>d(e).parents(".swiper")[0]===t.el)))),"bullets"===e.type&&e.clickable&&s.addClass(e.clickableClass),s.addClass(e.modifierClass+e.type),s.addClass(t.isHorizontal()?e.horizontalClass:e.verticalClass),"bullets"===e.type&&e.dynamicBullets&&(s.addClass(`${e.modifierClass}${e.type}-dynamic`),l=0,e.dynamicMainBullets<1&&(e.dynamicMainBullets=1)),"progressbar"===e.type&&e.progressbarOpposite&&s.addClass(e.progressbarOppositeClass),e.clickable&&s.on("click",U(e.bulletClass),(function(e){e.preventDefault();let s=d(this).index()*t.params.slidesPerGroup;t.params.loop&&(s+=t.loopedSlides),t.slideTo(s)})),Object.assign(t.pagination,{$el:s,el:s[0]}),t.enabled||s.addClass(e.lockClass))}function m(){const e=t.params.pagination;if(o())return;const s=t.pagination.$el;s.removeClass(e.hiddenClass),s.removeClass(e.modifierClass+e.type),s.removeClass(t.isHorizontal()?e.horizontalClass:e.verticalClass),t.pagination.bullets&&t.pagination.bullets.removeClass&&t.pagination.bullets.removeClass(e.bulletActiveClass),e.clickable&&s.off("click",U(e.bulletClass))}a("init",(()=>{!1===t.params.pagination.enabled?f():(h(),u(),p())})),a("activeIndexChange",(()=>{(t.params.loop||void 0===t.snapIndex)&&p()})),a("snapIndexChange",(()=>{t.params.loop||p()})),a("slidesLengthChange",(()=>{t.params.loop&&(u(),p())})),a("snapGridLengthChange",(()=>{t.params.loop||(u(),p())})),a("destroy",(()=>{m()})),a("enable disable",(()=>{const{$el:e}=t.pagination;e&&e[t.enabled?"removeClass":"addClass"](t.params.pagination.lockClass)})),a("lock unlock",(()=>{p()})),a("click",((e,s)=>{const a=s.target,{$el:r}=t.pagination;if(t.params.pagination.el&&t.params.pagination.hideOnClick&&r&&r.length>0&&!d(a).hasClass(t.params.pagination.bulletClass)){if(t.navigation&&(t.navigation.nextEl&&a===t.navigation.nextEl||t.navigation.prevEl&&a===t.navigation.prevEl))return;const e=r.hasClass(t.params.pagination.hiddenClass);i(!0===e?"paginationShow":"paginationHide"),r.toggleClass(t.params.pagination.hiddenClass)}}));const f=()=>{t.$el.addClass(t.params.pagination.paginationDisabledClass),t.pagination.$el&&t.pagination.$el.addClass(t.params.pagination.paginationDisabledClass),m()};Object.assign(t.pagination,{enable:()=>{t.$el.removeClass(t.params.pagination.paginationDisabledClass),t.pagination.$el&&t.pagination.$el.removeClass(t.params.pagination.paginationDisabledClass),h(),u(),p()},disable:f,render:u,update:p,init:h,destroy:m})},function(e){let{swiper:t,extendParams:s,on:i,emit:r}=e;const n=a();let l,o,c,u,h=!1,m=null,f=null;function g(){if(!t.params.scrollbar.el||!t.scrollbar.el)return;const{scrollbar:e,rtlTranslate:s,progress:a}=t,{$dragEl:i,$el:r}=e,n=t.params.scrollbar;let l=o,d=(c-o)*a;s?(d=-d,d>0?(l=o-d,d=0):-d+o>c&&(l=c+d)):d<0?(l=o+d,d=0):d+o>c&&(l=c-d),t.isHorizontal()?(i.transform(`translate3d(${d}px, 0, 0)`),i[0].style.width=`${l}px`):(i.transform(`translate3d(0px, ${d}px, 0)`),i[0].style.height=`${l}px`),n.hide&&(clearTimeout(m),r[0].style.opacity=1,m=setTimeout((()=>{r[0].style.opacity=0,r.transition(400)}),1e3))}function v(){if(!t.params.scrollbar.el||!t.scrollbar.el)return;const{scrollbar:e}=t,{$dragEl:s,$el:a}=e;s[0].style.width="",s[0].style.height="",c=t.isHorizontal()?a[0].offsetWidth:a[0].offsetHeight,u=t.size/(t.virtualSize+t.params.slidesOffsetBefore-(t.params.centeredSlides?t.snapGrid[0]:0)),o="auto"===t.params.scrollbar.dragSize?c*u:parseInt(t.params.scrollbar.dragSize,10),t.isHorizontal()?s[0].style.width=`${o}px`:s[0].style.height=`${o}px`,a[0].style.display=u>=1?"none":"",t.params.scrollbar.hide&&(a[0].style.opacity=0),t.params.watchOverflow&&t.enabled&&e.$el[t.isLocked?"addClass":"removeClass"](t.params.scrollbar.lockClass)}function w(e){return t.isHorizontal()?"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientX:e.clientX:"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientY:e.clientY}function b(e){const{scrollbar:s,rtlTranslate:a}=t,{$el:i}=s;let r;r=(w(e)-i.offset()[t.isHorizontal()?"left":"top"]-(null!==l?l:o/2))/(c-o),r=Math.max(Math.min(r,1),0),a&&(r=1-r);const n=t.minTranslate()+(t.maxTranslate()-t.minTranslate())*r;t.updateProgress(n),t.setTranslate(n),t.updateActiveIndex(),t.updateSlidesClasses()}function x(e){const s=t.params.scrollbar,{scrollbar:a,$wrapperEl:i}=t,{$el:n,$dragEl:o}=a;h=!0,l=e.target===o[0]||e.target===o?w(e)-e.target.getBoundingClientRect()[t.isHorizontal()?"left":"top"]:null,e.preventDefault(),e.stopPropagation(),i.transition(100),o.transition(100),b(e),clearTimeout(f),n.transition(0),s.hide&&n.css("opacity",1),t.params.cssMode&&t.$wrapperEl.css("scroll-snap-type","none"),r("scrollbarDragStart",e)}function y(e){const{scrollbar:s,$wrapperEl:a}=t,{$el:i,$dragEl:n}=s;h&&(e.preventDefault?e.preventDefault():e.returnValue=!1,b(e),a.transition(0),i.transition(0),n.transition(0),r("scrollbarDragMove",e))}function E(e){const s=t.params.scrollbar,{scrollbar:a,$wrapperEl:i}=t,{$el:n}=a;h&&(h=!1,t.params.cssMode&&(t.$wrapperEl.css("scroll-snap-type",""),i.transition("")),s.hide&&(clearTimeout(f),f=p((()=>{n.css("opacity",0),n.transition(400)}),1e3)),r("scrollbarDragEnd",e),s.snapOnRelease&&t.slideToClosest())}function C(e){const{scrollbar:s,touchEventsTouch:a,touchEventsDesktop:i,params:r,support:l}=t,o=s.$el;if(!o)return;const d=o[0],c=!(!l.passiveListener||!r.passiveListeners)&&{passive:!1,capture:!1},p=!(!l.passiveListener||!r.passiveListeners)&&{passive:!0,capture:!1};if(!d)return;const u="on"===e?"addEventListener":"removeEventListener";l.touch?(d[u](a.start,x,c),d[u](a.move,y,c),d[u](a.end,E,p)):(d[u](i.start,x,c),n[u](i.move,y,c),n[u](i.end,E,p))}function T(){const{scrollbar:e,$el:s}=t;t.params.scrollbar=F(t,t.originalParams.scrollbar,t.params.scrollbar,{el:"swiper-scrollbar"});const a=t.params.scrollbar;if(!a.el)return;let i=d(a.el);t.params.uniqueNavElements&&"string"==typeof a.el&&i.length>1&&1===s.find(a.el).length&&(i=s.find(a.el)),i.addClass(t.isHorizontal()?a.horizontalClass:a.verticalClass);let r=i.find(`.${t.params.scrollbar.dragClass}`);0===r.length&&(r=d(`
`),i.append(r)),Object.assign(e,{$el:i,el:i[0],$dragEl:r,dragEl:r[0]}),a.draggable&&t.params.scrollbar.el&&t.scrollbar.el&&C("on"),i&&i[t.enabled?"removeClass":"addClass"](t.params.scrollbar.lockClass)}function $(){const e=t.params.scrollbar,s=t.scrollbar.$el;s&&s.removeClass(t.isHorizontal()?e.horizontalClass:e.verticalClass),t.params.scrollbar.el&&t.scrollbar.el&&C("off")}s({scrollbar:{el:null,dragSize:"auto",hide:!1,draggable:!1,snapOnRelease:!0,lockClass:"swiper-scrollbar-lock",dragClass:"swiper-scrollbar-drag",scrollbarDisabledClass:"swiper-scrollbar-disabled",horizontalClass:"swiper-scrollbar-horizontal",verticalClass:"swiper-scrollbar-vertical"}}),t.scrollbar={el:null,dragEl:null,$el:null,$dragEl:null},i("init",(()=>{!1===t.params.scrollbar.enabled?S():(T(),v(),g())})),i("update resize observerUpdate lock unlock",(()=>{v()})),i("setTranslate",(()=>{g()})),i("setTransition",((e,s)=>{!function(e){t.params.scrollbar.el&&t.scrollbar.el&&t.scrollbar.$dragEl.transition(e)}(s)})),i("enable disable",(()=>{const{$el:e}=t.scrollbar;e&&e[t.enabled?"removeClass":"addClass"](t.params.scrollbar.lockClass)})),i("destroy",(()=>{$()}));const S=()=>{t.$el.addClass(t.params.scrollbar.scrollbarDisabledClass),t.scrollbar.$el&&t.scrollbar.$el.addClass(t.params.scrollbar.scrollbarDisabledClass),$()};Object.assign(t.scrollbar,{enable:()=>{t.$el.removeClass(t.params.scrollbar.scrollbarDisabledClass),t.scrollbar.$el&&t.scrollbar.$el.removeClass(t.params.scrollbar.scrollbarDisabledClass),T(),v(),g()},disable:S,updateSize:v,setTranslate:g,init:T,destroy:$})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({parallax:{enabled:!1}});const i=(e,s)=>{const{rtl:a}=t,i=d(e),r=a?-1:1,n=i.attr("data-swiper-parallax")||"0";let l=i.attr("data-swiper-parallax-x"),o=i.attr("data-swiper-parallax-y");const c=i.attr("data-swiper-parallax-scale"),p=i.attr("data-swiper-parallax-opacity");if(l||o?(l=l||"0",o=o||"0"):t.isHorizontal()?(l=n,o="0"):(o=n,l="0"),l=l.indexOf("%")>=0?parseInt(l,10)*s*r+"%":l*s*r+"px",o=o.indexOf("%")>=0?parseInt(o,10)*s+"%":o*s+"px",null!=p){const e=p-(p-1)*(1-Math.abs(s));i[0].style.opacity=e}if(null==c)i.transform(`translate3d(${l}, ${o}, 0px)`);else{const e=c-(c-1)*(1-Math.abs(s));i.transform(`translate3d(${l}, ${o}, 0px) scale(${e})`)}},r=()=>{const{$el:e,slides:s,progress:a,snapGrid:r}=t;e.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((e=>{i(e,a)})),s.each(((e,s)=>{let n=e.progress;t.params.slidesPerGroup>1&&"auto"!==t.params.slidesPerView&&(n+=Math.ceil(s/2)-a*(r.length-1)),n=Math.min(Math.max(n,-1),1),d(e).find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((e=>{i(e,n)}))}))};a("beforeInit",(()=>{t.params.parallax.enabled&&(t.params.watchSlidesProgress=!0,t.originalParams.watchSlidesProgress=!0)})),a("init",(()=>{t.params.parallax.enabled&&r()})),a("setTranslate",(()=>{t.params.parallax.enabled&&r()})),a("setTransition",((e,s)=>{t.params.parallax.enabled&&function(e){void 0===e&&(e=t.params.speed);const{$el:s}=t;s.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((t=>{const s=d(t);let a=parseInt(s.attr("data-swiper-parallax-duration"),10)||e;0===e&&(a=0),s.transition(a)}))}(s)}))},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;const n=r();s({zoom:{enabled:!1,maxRatio:3,minRatio:1,toggle:!0,containerClass:"swiper-zoom-container",zoomedSlideClass:"swiper-slide-zoomed"}}),t.zoom={enabled:!1};let l,o,c,p=1,u=!1;const m={$slideEl:void 0,slideWidth:void 0,slideHeight:void 0,$imageEl:void 0,$imageWrapEl:void 0,maxRatio:3},f={isTouched:void 0,isMoved:void 0,currentX:void 0,currentY:void 0,minX:void 0,minY:void 0,maxX:void 0,maxY:void 0,width:void 0,height:void 0,startX:void 0,startY:void 0,touchesStart:{},touchesCurrent:{}},g={x:void 0,y:void 0,prevPositionX:void 0,prevPositionY:void 0,prevTime:void 0};let v=1;function w(e){if(e.targetTouches.length<2)return 1;const t=e.targetTouches[0].pageX,s=e.targetTouches[0].pageY,a=e.targetTouches[1].pageX,i=e.targetTouches[1].pageY;return Math.sqrt((a-t)**2+(i-s)**2)}function b(e){const s=t.support,a=t.params.zoom;if(o=!1,c=!1,!s.gestures){if("touchstart"!==e.type||"touchstart"===e.type&&e.targetTouches.length<2)return;o=!0,m.scaleStart=w(e)}m.$slideEl&&m.$slideEl.length||(m.$slideEl=d(e.target).closest(`.${t.params.slideClass}`),0===m.$slideEl.length&&(m.$slideEl=t.slides.eq(t.activeIndex)),m.$imageEl=m.$slideEl.find(`.${a.containerClass}`).eq(0).find("picture, img, svg, canvas, .swiper-zoom-target").eq(0),m.$imageWrapEl=m.$imageEl.parent(`.${a.containerClass}`),m.maxRatio=m.$imageWrapEl.attr("data-swiper-zoom")||a.maxRatio,0!==m.$imageWrapEl.length)?(m.$imageEl&&m.$imageEl.transition(0),u=!0):m.$imageEl=void 0}function x(e){const s=t.support,a=t.params.zoom,i=t.zoom;if(!s.gestures){if("touchmove"!==e.type||"touchmove"===e.type&&e.targetTouches.length<2)return;c=!0,m.scaleMove=w(e)}m.$imageEl&&0!==m.$imageEl.length?(s.gestures?i.scale=e.scale*p:i.scale=m.scaleMove/m.scaleStart*p,i.scale>m.maxRatio&&(i.scale=m.maxRatio-1+(i.scale-m.maxRatio+1)**.5),i.scalef.touchesStart.x))return void(f.isTouched=!1);if(!t.isHorizontal()&&(Math.floor(f.minY)===Math.floor(f.startY)&&f.touchesCurrent.yf.touchesStart.y))return void(f.isTouched=!1)}e.cancelable&&e.preventDefault(),e.stopPropagation(),f.isMoved=!0,f.currentX=f.touchesCurrent.x-f.touchesStart.x+f.startX,f.currentY=f.touchesCurrent.y-f.touchesStart.y+f.startY,f.currentXf.maxX&&(f.currentX=f.maxX-1+(f.currentX-f.maxX+1)**.8),f.currentYf.maxY&&(f.currentY=f.maxY-1+(f.currentY-f.maxY+1)**.8),g.prevPositionX||(g.prevPositionX=f.touchesCurrent.x),g.prevPositionY||(g.prevPositionY=f.touchesCurrent.y),g.prevTime||(g.prevTime=Date.now()),g.x=(f.touchesCurrent.x-g.prevPositionX)/(Date.now()-g.prevTime)/2,g.y=(f.touchesCurrent.y-g.prevPositionY)/(Date.now()-g.prevTime)/2,Math.abs(f.touchesCurrent.x-g.prevPositionX)<2&&(g.x=0),Math.abs(f.touchesCurrent.y-g.prevPositionY)<2&&(g.y=0),g.prevPositionX=f.touchesCurrent.x,g.prevPositionY=f.touchesCurrent.y,g.prevTime=Date.now(),m.$imageWrapEl.transform(`translate3d(${f.currentX}px, ${f.currentY}px,0)`)}}function C(){const e=t.zoom;m.$slideEl&&t.previousIndex!==t.activeIndex&&(m.$imageEl&&m.$imageEl.transform("translate3d(0,0,0) scale(1)"),m.$imageWrapEl&&m.$imageWrapEl.transform("translate3d(0,0,0)"),e.scale=1,p=1,m.$slideEl=void 0,m.$imageEl=void 0,m.$imageWrapEl=void 0)}function T(e){const s=t.zoom,a=t.params.zoom;if(m.$slideEl||(e&&e.target&&(m.$slideEl=d(e.target).closest(`.${t.params.slideClass}`)),m.$slideEl||(t.params.virtual&&t.params.virtual.enabled&&t.virtual?m.$slideEl=t.$wrapperEl.children(`.${t.params.slideActiveClass}`):m.$slideEl=t.slides.eq(t.activeIndex)),m.$imageEl=m.$slideEl.find(`.${a.containerClass}`).eq(0).find("picture, img, svg, canvas, .swiper-zoom-target").eq(0),m.$imageWrapEl=m.$imageEl.parent(`.${a.containerClass}`)),!m.$imageEl||0===m.$imageEl.length||!m.$imageWrapEl||0===m.$imageWrapEl.length)return;let i,r,l,o,c,u,h,g,v,w,b,x,y,E,C,T,$,S;t.params.cssMode&&(t.wrapperEl.style.overflow="hidden",t.wrapperEl.style.touchAction="none"),m.$slideEl.addClass(`${a.zoomedSlideClass}`),void 0===f.touchesStart.x&&e?(i="touchend"===e.type?e.changedTouches[0].pageX:e.pageX,r="touchend"===e.type?e.changedTouches[0].pageY:e.pageY):(i=f.touchesStart.x,r=f.touchesStart.y),s.scale=m.$imageWrapEl.attr("data-swiper-zoom")||a.maxRatio,p=m.$imageWrapEl.attr("data-swiper-zoom")||a.maxRatio,e?($=m.$slideEl[0].offsetWidth,S=m.$slideEl[0].offsetHeight,l=m.$slideEl.offset().left+n.scrollX,o=m.$slideEl.offset().top+n.scrollY,c=l+$/2-i,u=o+S/2-r,v=m.$imageEl[0].offsetWidth,w=m.$imageEl[0].offsetHeight,b=v*s.scale,x=w*s.scale,y=Math.min($/2-b/2,0),E=Math.min(S/2-x/2,0),C=-y,T=-E,h=c*s.scale,g=u*s.scale,hC&&(h=C),gT&&(g=T)):(h=0,g=0),m.$imageWrapEl.transition(300).transform(`translate3d(${h}px, ${g}px,0)`),m.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${s.scale})`)}function $(){const e=t.zoom,s=t.params.zoom;m.$slideEl||(t.params.virtual&&t.params.virtual.enabled&&t.virtual?m.$slideEl=t.$wrapperEl.children(`.${t.params.slideActiveClass}`):m.$slideEl=t.slides.eq(t.activeIndex),m.$imageEl=m.$slideEl.find(`.${s.containerClass}`).eq(0).find("picture, img, svg, canvas, .swiper-zoom-target").eq(0),m.$imageWrapEl=m.$imageEl.parent(`.${s.containerClass}`)),m.$imageEl&&0!==m.$imageEl.length&&m.$imageWrapEl&&0!==m.$imageWrapEl.length&&(t.params.cssMode&&(t.wrapperEl.style.overflow="",t.wrapperEl.style.touchAction=""),e.scale=1,p=1,m.$imageWrapEl.transition(300).transform("translate3d(0,0,0)"),m.$imageEl.transition(300).transform("translate3d(0,0,0) scale(1)"),m.$slideEl.removeClass(`${s.zoomedSlideClass}`),m.$slideEl=void 0)}function S(e){const s=t.zoom;s.scale&&1!==s.scale?$():T(e)}function M(){const e=t.support;return{passiveListener:!("touchstart"!==t.touchEvents.start||!e.passiveListener||!t.params.passiveListeners)&&{passive:!0,capture:!1},activeListenerWithCapture:!e.passiveListener||{passive:!1,capture:!0}}}function P(){return`.${t.params.slideClass}`}function k(e){const{passiveListener:s}=M(),a=P();t.$wrapperEl[e]("gesturestart",a,b,s),t.$wrapperEl[e]("gesturechange",a,x,s),t.$wrapperEl[e]("gestureend",a,y,s)}function z(){l||(l=!0,k("on"))}function L(){l&&(l=!1,k("off"))}function O(){const e=t.zoom;if(e.enabled)return;e.enabled=!0;const s=t.support,{passiveListener:a,activeListenerWithCapture:i}=M(),r=P();s.gestures?(t.$wrapperEl.on(t.touchEvents.start,z,a),t.$wrapperEl.on(t.touchEvents.end,L,a)):"touchstart"===t.touchEvents.start&&(t.$wrapperEl.on(t.touchEvents.start,r,b,a),t.$wrapperEl.on(t.touchEvents.move,r,x,i),t.$wrapperEl.on(t.touchEvents.end,r,y,a),t.touchEvents.cancel&&t.$wrapperEl.on(t.touchEvents.cancel,r,y,a)),t.$wrapperEl.on(t.touchEvents.move,`.${t.params.zoom.containerClass}`,E,i)}function I(){const e=t.zoom;if(!e.enabled)return;const s=t.support;e.enabled=!1;const{passiveListener:a,activeListenerWithCapture:i}=M(),r=P();s.gestures?(t.$wrapperEl.off(t.touchEvents.start,z,a),t.$wrapperEl.off(t.touchEvents.end,L,a)):"touchstart"===t.touchEvents.start&&(t.$wrapperEl.off(t.touchEvents.start,r,b,a),t.$wrapperEl.off(t.touchEvents.move,r,x,i),t.$wrapperEl.off(t.touchEvents.end,r,y,a),t.touchEvents.cancel&&t.$wrapperEl.off(t.touchEvents.cancel,r,y,a)),t.$wrapperEl.off(t.touchEvents.move,`.${t.params.zoom.containerClass}`,E,i)}Object.defineProperty(t.zoom,"scale",{get:()=>v,set(e){if(v!==e){const t=m.$imageEl?m.$imageEl[0]:void 0,s=m.$slideEl?m.$slideEl[0]:void 0;i("zoomChange",e,t,s)}v=e}}),a("init",(()=>{t.params.zoom.enabled&&O()})),a("destroy",(()=>{I()})),a("touchStart",((e,s)=>{t.zoom.enabled&&function(e){const s=t.device;m.$imageEl&&0!==m.$imageEl.length&&(f.isTouched||(s.android&&e.cancelable&&e.preventDefault(),f.isTouched=!0,f.touchesStart.x="touchstart"===e.type?e.targetTouches[0].pageX:e.pageX,f.touchesStart.y="touchstart"===e.type?e.targetTouches[0].pageY:e.pageY))}(s)})),a("touchEnd",((e,s)=>{t.zoom.enabled&&function(){const e=t.zoom;if(!m.$imageEl||0===m.$imageEl.length)return;if(!f.isTouched||!f.isMoved)return f.isTouched=!1,void(f.isMoved=!1);f.isTouched=!1,f.isMoved=!1;let s=300,a=300;const i=g.x*s,r=f.currentX+i,n=g.y*a,l=f.currentY+n;0!==g.x&&(s=Math.abs((r-f.currentX)/g.x)),0!==g.y&&(a=Math.abs((l-f.currentY)/g.y));const o=Math.max(s,a);f.currentX=r,f.currentY=l;const d=f.width*e.scale,c=f.height*e.scale;f.minX=Math.min(m.slideWidth/2-d/2,0),f.maxX=-f.minX,f.minY=Math.min(m.slideHeight/2-c/2,0),f.maxY=-f.minY,f.currentX=Math.max(Math.min(f.currentX,f.maxX),f.minX),f.currentY=Math.max(Math.min(f.currentY,f.maxY),f.minY),m.$imageWrapEl.transition(o).transform(`translate3d(${f.currentX}px, ${f.currentY}px,0)`)}()})),a("doubleTap",((e,s)=>{!t.animating&&t.params.zoom.enabled&&t.zoom.enabled&&t.params.zoom.toggle&&S(s)})),a("transitionEnd",(()=>{t.zoom.enabled&&t.params.zoom.enabled&&C()})),a("slideChange",(()=>{t.zoom.enabled&&t.params.zoom.enabled&&t.params.cssMode&&C()})),Object.assign(t.zoom,{enable:O,disable:I,in:T,out:$,toggle:S})},function(e){let{swiper:t,extendParams:s,on:a,emit:i}=e;s({lazy:{checkInView:!1,enabled:!1,loadPrevNext:!1,loadPrevNextAmount:1,loadOnTransitionStart:!1,scrollingElement:"",elementClass:"swiper-lazy",loadingClass:"swiper-lazy-loading",loadedClass:"swiper-lazy-loaded",preloaderClass:"swiper-lazy-preloader"}}),t.lazy={};let n=!1,l=!1;function o(e,s){void 0===s&&(s=!0);const a=t.params.lazy;if(void 0===e)return;if(0===t.slides.length)return;const r=t.virtual&&t.params.virtual.enabled?t.$wrapperEl.children(`.${t.params.slideClass}[data-swiper-slide-index="${e}"]`):t.slides.eq(e),n=r.find(`.${a.elementClass}:not(.${a.loadedClass}):not(.${a.loadingClass})`);!r.hasClass(a.elementClass)||r.hasClass(a.loadedClass)||r.hasClass(a.loadingClass)||n.push(r[0]),0!==n.length&&n.each((e=>{const n=d(e);n.addClass(a.loadingClass);const l=n.attr("data-background"),c=n.attr("data-src"),p=n.attr("data-srcset"),u=n.attr("data-sizes"),h=n.parent("picture");t.loadImage(n[0],c||l,p,u,!1,(()=>{if(null!=t&&t&&(!t||t.params)&&!t.destroyed){if(l?(n.css("background-image",`url("${l}")`),n.removeAttr("data-background")):(p&&(n.attr("srcset",p),n.removeAttr("data-srcset")),u&&(n.attr("sizes",u),n.removeAttr("data-sizes")),h.length&&h.children("source").each((e=>{const t=d(e);t.attr("data-srcset")&&(t.attr("srcset",t.attr("data-srcset")),t.removeAttr("data-srcset"))})),c&&(n.attr("src",c),n.removeAttr("data-src"))),n.addClass(a.loadedClass).removeClass(a.loadingClass),r.find(`.${a.preloaderClass}`).remove(),t.params.loop&&s){const e=r.attr("data-swiper-slide-index");if(r.hasClass(t.params.slideDuplicateClass)){o(t.$wrapperEl.children(`[data-swiper-slide-index="${e}"]:not(.${t.params.slideDuplicateClass})`).index(),!1)}else{o(t.$wrapperEl.children(`.${t.params.slideDuplicateClass}[data-swiper-slide-index="${e}"]`).index(),!1)}}i("lazyImageReady",r[0],n[0]),t.params.autoHeight&&t.updateAutoHeight()}})),i("lazyImageLoad",r[0],n[0])}))}function c(){const{$wrapperEl:e,params:s,slides:a,activeIndex:i}=t,r=t.virtual&&s.virtual.enabled,n=s.lazy;let c=s.slidesPerView;function p(t){if(r){if(e.children(`.${s.slideClass}[data-swiper-slide-index="${t}"]`).length)return!0}else if(a[t])return!0;return!1}function u(e){return r?d(e).attr("data-swiper-slide-index"):d(e).index()}if("auto"===c&&(c=0),l||(l=!0),t.params.watchSlidesProgress)e.children(`.${s.slideVisibleClass}`).each((e=>{o(r?d(e).attr("data-swiper-slide-index"):d(e).index())}));else if(c>1)for(let e=i;e1||n.loadPrevNextAmount&&n.loadPrevNextAmount>1){const e=n.loadPrevNextAmount,t=Math.ceil(c),s=Math.min(i+t+Math.max(e,t),a.length),r=Math.max(i-Math.max(t,e),0);for(let e=i+t;e0&&o(u(t));const a=e.children(`.${s.slidePrevClass}`);a.length>0&&o(u(a))}}function p(){const e=r();if(!t||t.destroyed)return;const s=t.params.lazy.scrollingElement?d(t.params.lazy.scrollingElement):d(e),a=s[0]===e,i=a?e.innerWidth:s[0].offsetWidth,l=a?e.innerHeight:s[0].offsetHeight,o=t.$el.offset(),{rtlTranslate:u}=t;let h=!1;u&&(o.left-=t.$el[0].scrollLeft);const m=[[o.left,o.top],[o.left+t.width,o.top],[o.left,o.top+t.height],[o.left+t.width,o.top+t.height]];for(let e=0;e=0&&t[0]<=i&&t[1]>=0&&t[1]<=l){if(0===t[0]&&0===t[1])continue;h=!0}}const f=!("touchstart"!==t.touchEvents.start||!t.support.passiveListener||!t.params.passiveListeners)&&{passive:!0,capture:!1};h?(c(),s.off("scroll",p,f)):n||(n=!0,s.on("scroll",p,f))}a("beforeInit",(()=>{t.params.lazy.enabled&&t.params.preloadImages&&(t.params.preloadImages=!1)})),a("init",(()=>{t.params.lazy.enabled&&(t.params.lazy.checkInView?p():c())})),a("scroll",(()=>{t.params.freeMode&&t.params.freeMode.enabled&&!t.params.freeMode.sticky&&c()})),a("scrollbarDragMove resize _freeModeNoMomentumRelease",(()=>{t.params.lazy.enabled&&(t.params.lazy.checkInView?p():c())})),a("transitionStart",(()=>{t.params.lazy.enabled&&(t.params.lazy.loadOnTransitionStart||!t.params.lazy.loadOnTransitionStart&&!l)&&(t.params.lazy.checkInView?p():c())})),a("transitionEnd",(()=>{t.params.lazy.enabled&&!t.params.lazy.loadOnTransitionStart&&(t.params.lazy.checkInView?p():c())})),a("slideChange",(()=>{const{lazy:e,cssMode:s,watchSlidesProgress:a,touchReleaseOnEdges:i,resistanceRatio:r}=t.params;e.enabled&&(s||a&&(i||0===r))&&c()})),a("destroy",(()=>{t.$el&&t.$el.find(`.${t.params.lazy.loadingClass}`).removeClass(t.params.lazy.loadingClass)})),Object.assign(t.lazy,{load:c,loadInSlide:o})},function(e){let{swiper:t,extendParams:s,on:a}=e;function i(e,t){const s=function(){let e,t,s;return(a,i)=>{for(t=-1,e=a.length;e-t>1;)s=e+t>>1,a[s]<=i?t=s:e=s;return e}}();let a,i;return this.x=e,this.y=t,this.lastIndex=e.length-1,this.interpolate=function(e){return e?(i=s(this.x,e),a=i-1,(e-this.x[a])*(this.y[i]-this.y[a])/(this.x[i]-this.x[a])+this.y[a]):0},this}function r(){t.controller.control&&t.controller.spline&&(t.controller.spline=void 0,delete t.controller.spline)}s({controller:{control:void 0,inverse:!1,by:"slide"}}),t.controller={control:void 0},a("beforeInit",(()=>{t.controller.control=t.params.controller.control})),a("update",(()=>{r()})),a("resize",(()=>{r()})),a("observerUpdate",(()=>{r()})),a("setTranslate",((e,s,a)=>{t.controller.control&&t.controller.setTranslate(s,a)})),a("setTransition",((e,s,a)=>{t.controller.control&&t.controller.setTransition(s,a)})),Object.assign(t.controller,{setTranslate:function(e,s){const a=t.controller.control;let r,n;const l=t.constructor;function o(e){const s=t.rtlTranslate?-t.translate:t.translate;"slide"===t.params.controller.by&&(!function(e){t.controller.spline||(t.controller.spline=t.params.loop?new i(t.slidesGrid,e.slidesGrid):new i(t.snapGrid,e.snapGrid))}(e),n=-t.controller.spline.interpolate(-s)),n&&"container"!==t.params.controller.by||(r=(e.maxTranslate()-e.minTranslate())/(t.maxTranslate()-t.minTranslate()),n=(s-t.minTranslate())*r+e.minTranslate()),t.params.controller.inverse&&(n=e.maxTranslate()-n),e.updateProgress(n),e.setTranslate(n,t),e.updateActiveIndex(),e.updateSlidesClasses()}if(Array.isArray(a))for(let e=0;e{s.updateAutoHeight()})),s.$wrapperEl.transitionEnd((()=>{i&&(s.params.loop&&"slide"===t.params.controller.by&&s.loopFix(),s.transitionEnd())})))}if(Array.isArray(i))for(r=0;r{n(e),"BUTTON"!==e[0].tagName&&(o(e,"button"),e.on("keydown",m)),p(e,s),function(e,t){e.attr("aria-controls",t)}(e,t)},w=()=>{t.a11y.clicked=!0},b=()=>{requestAnimationFrame((()=>{requestAnimationFrame((()=>{t.destroyed||(t.a11y.clicked=!1)}))}))},x=e=>{if(t.a11y.clicked)return;const s=e.target.closest(`.${t.params.slideClass}`);if(!s||!t.slides.includes(s))return;const a=t.slides.indexOf(s)===t.activeIndex,i=t.params.watchSlidesProgress&&t.visibleSlides&&t.visibleSlides.includes(s);a||i||e.sourceCapabilities&&e.sourceCapabilities.firesTouchEvents||(t.isHorizontal()?t.el.scrollLeft=0:t.el.scrollTop=0,t.slideTo(t.slides.indexOf(s),0))},y=()=>{const e=t.params.a11y;e.itemRoleDescriptionMessage&&c(d(t.slides),e.itemRoleDescriptionMessage),e.slideRole&&o(d(t.slides),e.slideRole);const s=t.params.loop?t.slides.filter((e=>!e.classList.contains(t.params.slideDuplicateClass))).length:t.slides.length;e.slideLabelMessage&&t.slides.each(((a,i)=>{const r=d(a),n=t.params.loop?parseInt(r.attr("data-swiper-slide-index"),10):i;p(r,e.slideLabelMessage.replace(/\{\{index\}\}/,n+1).replace(/\{\{slidesLength\}\}/,s))}))},E=()=>{const e=t.params.a11y;t.$el.append(i);const s=t.$el;e.containerRoleDescriptionMessage&&c(s,e.containerRoleDescriptionMessage),e.containerMessage&&p(s,e.containerMessage);const a=t.$wrapperEl,r=e.id||a.attr("id")||`swiper-wrapper-${n=16,void 0===n&&(n=16),"x".repeat(n).replace(/x/g,(()=>Math.round(16*Math.random()).toString(16)))}`;var n;const l=t.params.autoplay&&t.params.autoplay.enabled?"off":"polite";var o;let d,u;o=r,a.attr("id",o),function(e,t){e.attr("aria-live",t)}(a,l),y(),t.navigation&&t.navigation.$nextEl&&(d=t.navigation.$nextEl),t.navigation&&t.navigation.$prevEl&&(u=t.navigation.$prevEl),d&&d.length&&v(d,r,e.nextSlideMessage),u&&u.length&&v(u,r,e.prevSlideMessage),g()&&t.pagination.$el.on("keydown",U(t.params.pagination.bulletClass),m),t.$el.on("focus",x,!0),t.$el.on("pointerdown",w,!0),t.$el.on("pointerup",b,!0)};a("beforeInit",(()=>{i=d(``)})),a("afterInit",(()=>{t.params.a11y.enabled&&E()})),a("slidesLengthChange snapGridLengthChange slidesGridLengthChange",(()=>{t.params.a11y.enabled&&y()})),a("fromEdge toEdge afterInit lock unlock",(()=>{t.params.a11y.enabled&&function(){if(t.params.loop||t.params.rewind||!t.navigation)return;const{$nextEl:e,$prevEl:s}=t.navigation;s&&s.length>0&&(t.isBeginning?(u(s),l(s)):(h(s),n(s))),e&&e.length>0&&(t.isEnd?(u(e),l(e)):(h(e),n(e)))}()})),a("paginationUpdate",(()=>{t.params.a11y.enabled&&function(){const e=t.params.a11y;f()&&t.pagination.bullets.each((s=>{const a=d(s);t.params.pagination.clickable&&(n(a),t.params.pagination.renderBullet||(o(a,"button"),p(a,e.paginationBulletMessage.replace(/\{\{index\}\}/,a.index()+1)))),a.is(`.${t.params.pagination.bulletActiveClass}`)?a.attr("aria-current","true"):a.removeAttr("aria-current")}))}()})),a("destroy",(()=>{t.params.a11y.enabled&&function(){let e,s;i&&i.length>0&&i.remove(),t.navigation&&t.navigation.$nextEl&&(e=t.navigation.$nextEl),t.navigation&&t.navigation.$prevEl&&(s=t.navigation.$prevEl),e&&e.off("keydown",m),s&&s.off("keydown",m),g()&&t.pagination.$el.off("keydown",U(t.params.pagination.bulletClass),m),t.$el.off("focus",x,!0),t.$el.off("pointerdown",w,!0),t.$el.off("pointerup",b,!0)}()}))},function(e){let{swiper:t,extendParams:s,on:a}=e;s({history:{enabled:!1,root:"",replaceState:!1,key:"slides",keepQuery:!1}});let i=!1,n={};const l=e=>e.toString().replace(/\s+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+/,"").replace(/-+$/,""),o=e=>{const t=r();let s;s=e?new URL(e):t.location;const a=s.pathname.slice(1).split("/").filter((e=>""!==e)),i=a.length;return{key:a[i-2],value:a[i-1]}},d=(e,s)=>{const a=r();if(!i||!t.params.history.enabled)return;let n;n=t.params.url?new URL(t.params.url):a.location;const o=t.slides.eq(s);let d=l(o.attr("data-history"));if(t.params.history.root.length>0){let s=t.params.history.root;"/"===s[s.length-1]&&(s=s.slice(0,s.length-1)),d=`${s}/${e}/${d}`}else n.pathname.includes(e)||(d=`${e}/${d}`);t.params.history.keepQuery&&(d+=n.search);const c=a.history.state;c&&c.value===d||(t.params.history.replaceState?a.history.replaceState({value:d},null,d):a.history.pushState({value:d},null,d))},c=(e,s,a)=>{if(s)for(let i=0,r=t.slides.length;i{n=o(t.params.url),c(t.params.speed,n.value,!1)};a("init",(()=>{t.params.history.enabled&&(()=>{const e=r();if(t.params.history){if(!e.history||!e.history.pushState)return t.params.history.enabled=!1,void(t.params.hashNavigation.enabled=!0);i=!0,n=o(t.params.url),(n.key||n.value)&&(c(0,n.value,t.params.runCallbacksOnInit),t.params.history.replaceState||e.addEventListener("popstate",p))}})()})),a("destroy",(()=>{t.params.history.enabled&&(()=>{const e=r();t.params.history.replaceState||e.removeEventListener("popstate",p)})()})),a("transitionEnd _freeModeNoMomentumRelease",(()=>{i&&d(t.params.history.key,t.activeIndex)})),a("slideChange",(()=>{i&&t.params.cssMode&&d(t.params.history.key,t.activeIndex)}))},function(e){let{swiper:t,extendParams:s,emit:i,on:n}=e,l=!1;const o=a(),c=r();s({hashNavigation:{enabled:!1,replaceState:!1,watchState:!1}});const p=()=>{i("hashChange");const e=o.location.hash.replace("#","");if(e!==t.slides.eq(t.activeIndex).attr("data-hash")){const s=t.$wrapperEl.children(`.${t.params.slideClass}[data-hash="${e}"]`).index();if(void 0===s)return;t.slideTo(s)}},u=()=>{if(l&&t.params.hashNavigation.enabled)if(t.params.hashNavigation.replaceState&&c.history&&c.history.replaceState)c.history.replaceState(null,null,`#${t.slides.eq(t.activeIndex).attr("data-hash")}`||""),i("hashSet");else{const e=t.slides.eq(t.activeIndex),s=e.attr("data-hash")||e.attr("data-history");o.location.hash=s||"",i("hashSet")}};n("init",(()=>{t.params.hashNavigation.enabled&&(()=>{if(!t.params.hashNavigation.enabled||t.params.history&&t.params.history.enabled)return;l=!0;const e=o.location.hash.replace("#","");if(e){const s=0;for(let a=0,i=t.slides.length;a{t.params.hashNavigation.enabled&&t.params.hashNavigation.watchState&&d(c).off("hashchange",p)})),n("transitionEnd _freeModeNoMomentumRelease",(()=>{l&&u()})),n("slideChange",(()=>{l&&t.params.cssMode&&u()}))},function(e){let t,{swiper:s,extendParams:i,on:r,emit:n}=e;function l(){if(!s.size)return s.autoplay.running=!1,void(s.autoplay.paused=!1);const e=s.slides.eq(s.activeIndex);let a=s.params.autoplay.delay;e.attr("data-swiper-autoplay")&&(a=e.attr("data-swiper-autoplay")||s.params.autoplay.delay),clearTimeout(t),t=p((()=>{let e;s.params.autoplay.reverseDirection?s.params.loop?(s.loopFix(),e=s.slidePrev(s.params.speed,!0,!0),n("autoplay")):s.isBeginning?s.params.autoplay.stopOnLastSlide?d():(e=s.slideTo(s.slides.length-1,s.params.speed,!0,!0),n("autoplay")):(e=s.slidePrev(s.params.speed,!0,!0),n("autoplay")):s.params.loop?(s.loopFix(),e=s.slideNext(s.params.speed,!0,!0),n("autoplay")):s.isEnd?s.params.autoplay.stopOnLastSlide?d():(e=s.slideTo(0,s.params.speed,!0,!0),n("autoplay")):(e=s.slideNext(s.params.speed,!0,!0),n("autoplay")),(s.params.cssMode&&s.autoplay.running||!1===e)&&l()}),a)}function o(){return void 0===t&&(!s.autoplay.running&&(s.autoplay.running=!0,n("autoplayStart"),l(),!0))}function d(){return!!s.autoplay.running&&(void 0!==t&&(t&&(clearTimeout(t),t=void 0),s.autoplay.running=!1,n("autoplayStop"),!0))}function c(e){s.autoplay.running&&(s.autoplay.paused||(t&&clearTimeout(t),s.autoplay.paused=!0,0!==e&&s.params.autoplay.waitForTransition?["transitionend","webkitTransitionEnd"].forEach((e=>{s.$wrapperEl[0].addEventListener(e,h)})):(s.autoplay.paused=!1,l())))}function u(){const e=a();"hidden"===e.visibilityState&&s.autoplay.running&&c(),"visible"===e.visibilityState&&s.autoplay.paused&&(l(),s.autoplay.paused=!1)}function h(e){s&&!s.destroyed&&s.$wrapperEl&&e.target===s.$wrapperEl[0]&&(["transitionend","webkitTransitionEnd"].forEach((e=>{s.$wrapperEl[0].removeEventListener(e,h)})),s.autoplay.paused=!1,s.autoplay.running?l():d())}function m(){s.params.autoplay.disableOnInteraction?d():(n("autoplayPause"),c()),["transitionend","webkitTransitionEnd"].forEach((e=>{s.$wrapperEl[0].removeEventListener(e,h)}))}function f(){s.params.autoplay.disableOnInteraction||(s.autoplay.paused=!1,n("autoplayResume"),l())}s.autoplay={running:!1,paused:!1},i({autoplay:{enabled:!1,delay:3e3,waitForTransition:!0,disableOnInteraction:!0,stopOnLastSlide:!1,reverseDirection:!1,pauseOnMouseEnter:!1}}),r("init",(()=>{if(s.params.autoplay.enabled){o();a().addEventListener("visibilitychange",u),s.params.autoplay.pauseOnMouseEnter&&(s.$el.on("mouseenter",m),s.$el.on("mouseleave",f))}})),r("beforeTransitionStart",((e,t,a)=>{s.autoplay.running&&(a||!s.params.autoplay.disableOnInteraction?s.autoplay.pause(t):d())})),r("sliderFirstMove",(()=>{s.autoplay.running&&(s.params.autoplay.disableOnInteraction?d():c())})),r("touchEnd",(()=>{s.params.cssMode&&s.autoplay.paused&&!s.params.autoplay.disableOnInteraction&&l()})),r("destroy",(()=>{s.$el.off("mouseenter",m),s.$el.off("mouseleave",f),s.autoplay.running&&d();a().removeEventListener("visibilitychange",u)})),Object.assign(s.autoplay,{pause:c,run:l,start:o,stop:d})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({thumbs:{swiper:null,multipleActiveThumbs:!0,autoScrollOffset:0,slideThumbActiveClass:"swiper-slide-thumb-active",thumbsContainerClass:"swiper-thumbs"}});let i=!1,r=!1;function n(){const e=t.thumbs.swiper;if(!e||e.destroyed)return;const s=e.clickedIndex,a=e.clickedSlide;if(a&&d(a).hasClass(t.params.thumbs.slideThumbActiveClass))return;if(null==s)return;let i;if(i=e.params.loop?parseInt(d(e.clickedSlide).attr("data-swiper-slide-index"),10):s,t.params.loop){let e=t.activeIndex;t.slides.eq(e).hasClass(t.params.slideDuplicateClass)&&(t.loopFix(),t._clientLeft=t.$wrapperEl[0].clientLeft,e=t.activeIndex);const s=t.slides.eq(e).prevAll(`[data-swiper-slide-index="${i}"]`).eq(0).index(),a=t.slides.eq(e).nextAll(`[data-swiper-slide-index="${i}"]`).eq(0).index();i=void 0===s?a:void 0===a?s:a-e1&&!t.params.centeredSlides&&(i=t.params.slidesPerView),t.params.thumbs.multipleActiveThumbs||(i=1),i=Math.floor(i),s.slides.removeClass(r),s.params.loop||s.params.virtual&&s.params.virtual.enabled)for(let e=0;e1?a:o:a-ot.previousIndex?"next":"prev"}else i=t.realIndex,r=i>t.previousIndex?"next":"prev";l&&(i+="next"===r?n:-1*n),s.visibleSlidesIndexes&&s.visibleSlidesIndexes.indexOf(i)<0&&(s.params.centeredSlides?i=i>o?i-Math.floor(a/2)+1:i+Math.floor(a/2)-1:i>o&&s.params.slidesPerGroup,s.slideTo(i,e?0:void 0))}}t.thumbs={swiper:null},a("beforeInit",(()=>{const{thumbs:e}=t.params;e&&e.swiper&&(l(),o(!0))})),a("slideChange update resize observerUpdate",(()=>{o()})),a("setTransition",((e,s)=>{const a=t.thumbs.swiper;a&&!a.destroyed&&a.setTransition(s)})),a("beforeDestroy",(()=>{const e=t.thumbs.swiper;e&&!e.destroyed&&r&&e.destroy()})),Object.assign(t.thumbs,{init:l,update:o})},function(e){let{swiper:t,extendParams:s,emit:a,once:i}=e;s({freeMode:{enabled:!1,momentum:!0,momentumRatio:1,momentumBounce:!0,momentumBounceRatio:1,momentumVelocityRatio:1,sticky:!1,minimumVelocity:.02}}),Object.assign(t,{freeMode:{onTouchStart:function(){const e=t.getTranslate();t.setTranslate(e),t.setTransition(0),t.touchEventsData.velocities.length=0,t.freeMode.onTouchEnd({currentPos:t.rtl?t.translate:-t.translate})},onTouchMove:function(){const{touchEventsData:e,touches:s}=t;0===e.velocities.length&&e.velocities.push({position:s[t.isHorizontal()?"startX":"startY"],time:e.touchStartTime}),e.velocities.push({position:s[t.isHorizontal()?"currentX":"currentY"],time:u()})},onTouchEnd:function(e){let{currentPos:s}=e;const{params:r,$wrapperEl:n,rtlTranslate:l,snapGrid:o,touchEventsData:d}=t,c=u()-d.touchStartTime;if(s<-t.minTranslate())t.slideTo(t.activeIndex);else if(s>-t.maxTranslate())t.slides.length1){const e=d.velocities.pop(),s=d.velocities.pop(),a=e.position-s.position,i=e.time-s.time;t.velocity=a/i,t.velocity/=2,Math.abs(t.velocity)150||u()-e.time>300)&&(t.velocity=0)}else t.velocity=0;t.velocity*=r.freeMode.momentumVelocityRatio,d.velocities.length=0;let e=1e3*r.freeMode.momentumRatio;const s=t.velocity*e;let c=t.translate+s;l&&(c=-c);let p,h=!1;const m=20*Math.abs(t.velocity)*r.freeMode.momentumBounceRatio;let f;if(ct.minTranslate())r.freeMode.momentumBounce?(c-t.minTranslate()>m&&(c=t.minTranslate()+m),p=t.minTranslate(),h=!0,d.allowMomentumBounce=!0):c=t.minTranslate(),r.loop&&r.centeredSlides&&(f=!0);else if(r.freeMode.sticky){let e;for(let t=0;t-c){e=t;break}c=Math.abs(o[e]-c){t.loopFix()})),0!==t.velocity){if(e=l?Math.abs((-c-t.translate)/t.velocity):Math.abs((c-t.translate)/t.velocity),r.freeMode.sticky){const s=Math.abs((l?-c:c)-t.translate),a=t.slidesSizesGrid[t.activeIndex];e=s{t&&!t.destroyed&&d.allowMomentumBounce&&(a("momentumBounce"),t.setTransition(r.speed),setTimeout((()=>{t.setTranslate(p),n.transitionEnd((()=>{t&&!t.destroyed&&t.transitionEnd()}))}),0))}))):t.velocity?(a("_freeModeNoMomentumRelease"),t.updateProgress(c),t.setTransition(e),t.setTranslate(c),t.transitionStart(!0,t.swipeDirection),t.animating||(t.animating=!0,n.transitionEnd((()=>{t&&!t.destroyed&&t.transitionEnd()})))):t.updateProgress(c),t.updateActiveIndex(),t.updateSlidesClasses()}else{if(r.freeMode.sticky)return void t.slideToClosest();r.freeMode&&a("_freeModeNoMomentumRelease")}(!r.freeMode.momentum||c>=r.longSwipesMs)&&(t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses())}}}})},function(e){let t,s,a,{swiper:i,extendParams:r}=e;r({grid:{rows:1,fill:"column"}}),i.grid={initSlides:e=>{const{slidesPerView:r}=i.params,{rows:n,fill:l}=i.params.grid;s=t/n,a=Math.floor(e/n),t=Math.floor(e/n)===e/n?e:Math.ceil(e/n)*n,"auto"!==r&&"row"===l&&(t=Math.max(t,r*n))},updateSlide:(e,r,n,l)=>{const{slidesPerGroup:o,spaceBetween:d}=i.params,{rows:c,fill:p}=i.params.grid;let u,h,m;if("row"===p&&o>1){const s=Math.floor(e/(o*c)),a=e-c*o*s,i=0===s?o:Math.min(Math.ceil((n-s*c*o)/c),o);m=Math.floor(a/i),h=a-m*i+s*o,u=h+m*t/c,r.css({"-webkit-order":u,order:u})}else"column"===p?(h=Math.floor(e/c),m=e-h*c,(h>a||h===a&&m===c-1)&&(m+=1,m>=c&&(m=0,h+=1))):(m=Math.floor(e/s),h=e-m*s);r.css(l("margin-top"),0!==m?d&&`${d}px`:"")},updateWrapperSize:(e,s,a)=>{const{spaceBetween:r,centeredSlides:n,roundLengths:l}=i.params,{rows:o}=i.params.grid;if(i.virtualSize=(e+r)*t,i.virtualSize=Math.ceil(i.virtualSize/o)-r,i.$wrapperEl.css({[a("width")]:`${i.virtualSize+r}px`}),n){s.splice(0,s.length);const e=[];for(let t=0;t{const{slides:e}=t,s=t.params.fadeEffect;for(let a=0;a{const{transformEl:s}=t.params.fadeEffect;(s?t.slides.find(s):t.slides).transition(e),ae({swiper:t,duration:e,transformEl:s,allSlides:!0})},overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!t.params.cssMode})})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94}});const i=(e,t,s)=>{let a=s?e.find(".swiper-slide-shadow-left"):e.find(".swiper-slide-shadow-top"),i=s?e.find(".swiper-slide-shadow-right"):e.find(".swiper-slide-shadow-bottom");0===a.length&&(a=d(`
`),e.append(a)),0===i.length&&(i=d(`
`),e.append(i)),a.length&&(a[0].style.opacity=Math.max(-t,0)),i.length&&(i[0].style.opacity=Math.max(t,0))};te({effect:"cube",swiper:t,on:a,setTranslate:()=>{const{$el:e,$wrapperEl:s,slides:a,width:r,height:n,rtlTranslate:l,size:o,browser:c}=t,p=t.params.cubeEffect,u=t.isHorizontal(),h=t.virtual&&t.params.virtual.enabled;let m,f=0;p.shadow&&(u?(m=s.find(".swiper-cube-shadow"),0===m.length&&(m=d('
'),s.append(m)),m.css({height:`${r}px`})):(m=e.find(".swiper-cube-shadow"),0===m.length&&(m=d('
'),e.append(m))));for(let e=0;e-1&&(f=90*s+90*d,l&&(f=90*-s-90*d)),t.transform(v),p.slideShadows&&i(t,d,u)}if(s.css({"-webkit-transform-origin":`50% 50% -${o/2}px`,"transform-origin":`50% 50% -${o/2}px`}),p.shadow)if(u)m.transform(`translate3d(0px, ${r/2+p.shadowOffset}px, ${-r/2}px) rotateX(90deg) rotateZ(0deg) scale(${p.shadowScale})`);else{const e=Math.abs(f)-90*Math.floor(Math.abs(f)/90),t=1.5-(Math.sin(2*e*Math.PI/360)/2+Math.cos(2*e*Math.PI/360)/2),s=p.shadowScale,a=p.shadowScale/t,i=p.shadowOffset;m.transform(`scale3d(${s}, 1, ${a}) translate3d(0px, ${n/2+i}px, ${-n/2/a}px) rotateX(-90deg)`)}const g=c.isSafari||c.isWebView?-o/2:0;s.transform(`translate3d(0px,0,${g}px) rotateX(${t.isHorizontal()?0:f}deg) rotateY(${t.isHorizontal()?-f:0}deg)`),s[0].style.setProperty("--swiper-cube-translate-z",`${g}px`)},setTransition:e=>{const{$el:s,slides:a}=t;a.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),t.params.cubeEffect.shadow&&!t.isHorizontal()&&s.find(".swiper-cube-shadow").transition(e)},recreateShadows:()=>{const e=t.isHorizontal();t.slides.each((t=>{const s=Math.max(Math.min(t.progress,1),-1);i(d(t),s,e)}))},getEffectParams:()=>t.params.cubeEffect,perspective:()=>!0,overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,resistanceRatio:0,spaceBetween:0,centeredSlides:!1,virtualTranslate:!0})})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({flipEffect:{slideShadows:!0,limitRotation:!0,transformEl:null}});const i=(e,s,a)=>{let i=t.isHorizontal()?e.find(".swiper-slide-shadow-left"):e.find(".swiper-slide-shadow-top"),r=t.isHorizontal()?e.find(".swiper-slide-shadow-right"):e.find(".swiper-slide-shadow-bottom");0===i.length&&(i=ie(a,e,t.isHorizontal()?"left":"top")),0===r.length&&(r=ie(a,e,t.isHorizontal()?"right":"bottom")),i.length&&(i[0].style.opacity=Math.max(-s,0)),r.length&&(r[0].style.opacity=Math.max(s,0))};te({effect:"flip",swiper:t,on:a,setTranslate:()=>{const{slides:e,rtlTranslate:s}=t,a=t.params.flipEffect;for(let r=0;r{const{transformEl:s}=t.params.flipEffect;(s?t.slides.find(s):t.slides).transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),ae({swiper:t,duration:e,transformEl:s})},recreateShadows:()=>{const e=t.params.flipEffect;t.slides.each((s=>{const a=d(s);let r=a[0].progress;t.params.flipEffect.limitRotation&&(r=Math.max(Math.min(s.progress,1),-1)),i(a,r,e)}))},getEffectParams:()=>t.params.flipEffect,perspective:()=>!0,overwriteParams:()=>({slidesPerView:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!t.params.cssMode})})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({coverflowEffect:{rotate:50,stretch:0,depth:100,scale:1,modifier:1,slideShadows:!0,transformEl:null}}),te({effect:"coverflow",swiper:t,on:a,setTranslate:()=>{const{width:e,height:s,slides:a,slidesSizesGrid:i}=t,r=t.params.coverflowEffect,n=t.isHorizontal(),l=t.translate,o=n?e/2-l:s/2-l,d=n?r.rotate:-r.rotate,c=r.depth;for(let e=0,t=a.length;e0?p:0),s.length&&(s[0].style.opacity=-p>0?-p:0)}}},setTransition:e=>{const{transformEl:s}=t.params.coverflowEffect;(s?t.slides.find(s):t.slides).transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)},perspective:()=>!0,overwriteParams:()=>({watchSlidesProgress:!0})})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({creativeEffect:{transformEl:null,limitProgress:1,shadowPerProgress:!1,progressMultiplier:1,perspective:!0,prev:{translate:[0,0,0],rotate:[0,0,0],opacity:1,scale:1},next:{translate:[0,0,0],rotate:[0,0,0],opacity:1,scale:1}}});const i=e=>"string"==typeof e?e:`${e}px`;te({effect:"creative",swiper:t,on:a,setTranslate:()=>{const{slides:e,$wrapperEl:s,slidesSizesGrid:a}=t,r=t.params.creativeEffect,{progressMultiplier:n}=r,l=t.params.centeredSlides;if(l){const e=a[0]/2-t.params.slidesOffsetBefore||0;s.transform(`translateX(calc(50% - ${e}px))`)}for(let s=0;s0&&(f=r.prev,m=!0),u.forEach(((e,t)=>{u[t]=`calc(${e}px + (${i(f.translate[t])} * ${Math.abs(d*n)}))`})),h.forEach(((e,t)=>{h[t]=f.rotate[t]*Math.abs(d*n)})),a[0].style.zIndex=-Math.abs(Math.round(o))+e.length;const g=u.join(", "),v=`rotateX(${h[0]}deg) rotateY(${h[1]}deg) rotateZ(${h[2]}deg)`,w=c<0?`scale(${1+(1-f.scale)*c*n})`:`scale(${1-(1-f.scale)*c*n})`,b=c<0?1+(1-f.opacity)*c*n:1-(1-f.opacity)*c*n,x=`translate3d(${g}) ${v} ${w}`;if(m&&f.shadow||!m){let e=a.children(".swiper-slide-shadow");if(0===e.length&&f.shadow&&(e=ie(r,a)),e.length){const t=r.shadowPerProgress?d*(1/r.limitProgress):d;e[0].style.opacity=Math.min(Math.max(Math.abs(t),0),1)}}const y=se(r,a);y.transform(x).css({opacity:b}),f.origin&&y.css("transform-origin",f.origin)}},setTransition:e=>{const{transformEl:s}=t.params.creativeEffect;(s?t.slides.find(s):t.slides).transition(e).find(".swiper-slide-shadow").transition(e),ae({swiper:t,duration:e,transformEl:s,allSlides:!0})},perspective:()=>t.params.creativeEffect.perspective,overwriteParams:()=>({watchSlidesProgress:!0,virtualTranslate:!t.params.cssMode})})},function(e){let{swiper:t,extendParams:s,on:a}=e;s({cardsEffect:{slideShadows:!0,transformEl:null,rotate:!0,perSlideRotate:2,perSlideOffset:8}}),te({effect:"cards",swiper:t,on:a,setTranslate:()=>{const{slides:e,activeIndex:s}=t,a=t.params.cardsEffect,{startTranslate:i,isTouched:r}=t.touchEventsData,n=t.translate;for(let l=0;l0&&c<1&&(r||t.params.cssMode)&&n-1&&(r||t.params.cssMode)&&n>i;if(b||x){const e=(1-Math.abs((Math.abs(c)-.5)/.5))**.5;g+=-28*c*e,f+=-.5*e,v+=96*e,h=-25*e*Math.abs(c)+"%"}if(u=c<0?`calc(${u}px + (${v*Math.abs(c)}%))`:c>0?`calc(${u}px + (-${v*Math.abs(c)}%))`:`${u}px`,!t.isHorizontal()){const e=h;h=u,u=e}const y=c<0?""+(1+(1-f)*c):""+(1-(1-f)*c),E=`\n translate3d(${u}, ${h}, ${m}px)\n rotateZ(${a.rotate?g:0}deg)\n scale(${y})\n `;if(a.slideShadows){let e=o.find(".swiper-slide-shadow");0===e.length&&(e=ie(a,o)),e.length&&(e[0].style.opacity=Math.min(Math.max((Math.abs(c)-.5)/.5,0),1))}o[0].style.zIndex=-Math.abs(Math.round(d))+e.length;se(a,o).transform(E)}},setTransition:e=>{const{transformEl:s}=t.params.cardsEffect;(s?t.slides.find(s):t.slides).transition(e).find(".swiper-slide-shadow").transition(e),ae({swiper:t,duration:e,transformEl:s})},perspective:()=>!0,overwriteParams:()=>({watchSlidesProgress:!0,virtualTranslate:!t.params.cssMode})})}];return V.use(re),V})); +//# sourceMappingURL=swiper-bundle.min.js.map \ No newline at end of file diff --git a/public/js/swiper.min.js b/public/js/swiper.min.js new file mode 100644 index 0000000..e6cfb82 --- /dev/null +++ b/public/js/swiper.min.js @@ -0,0 +1,14 @@ +/** + * Swiper 5.3.6 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://swiperjs.com + * + * Copyright 2014-2020 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 29, 2020 + */ + +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Swiper=t()}(this,(function(){"use strict";var e="undefined"==typeof document?{body:{},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},location:{hash:""}}:document,t="undefined"==typeof window?{document:e,navigator:{userAgent:""},location:{},history:{},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){}}:window,i=function(e){for(var t=0;t=0&&d.indexOf(">")>=0){var h="div";for(0===d.indexOf(":~]/)?(a||e).querySelectorAll(s.trim()):[e.getElementById(s.trim().split("#")[1])],n=0;n0&&s[0].nodeType)for(n=0;n=0;u-=1){var v=c[u];r&&v.listener===r?(p.removeEventListener(d,v.proxyListener,n),c.splice(u,1)):r&&v.listener&&v.listener.dom7proxy&&v.listener.dom7proxy===r?(p.removeEventListener(d,v.proxyListener,n),c.splice(u,1)):r||(p.removeEventListener(d,v.proxyListener,n),c.splice(u,1))}}return this},trigger:function(){for(var i=[],s=arguments.length;s--;)i[s]=arguments[s];for(var a=i[0].split(" "),r=i[1],n=0;n0})),d.dispatchEvent(h),d.dom7EventData=[],delete d.dom7EventData}return this},transitionEnd:function(e){var t,i=["webkitTransitionEnd","transitionend"],s=this;function a(r){if(r.target===this)for(e.call(this,r),t=0;t0){if(e){var t=this.styles();return this[0].offsetWidth+parseFloat(t.getPropertyValue("margin-right"))+parseFloat(t.getPropertyValue("margin-left"))}return this[0].offsetWidth}return null},outerHeight:function(e){if(this.length>0){if(e){var t=this.styles();return this[0].offsetHeight+parseFloat(t.getPropertyValue("margin-top"))+parseFloat(t.getPropertyValue("margin-bottom"))}return this[0].offsetHeight}return null},offset:function(){if(this.length>0){var i=this[0],s=i.getBoundingClientRect(),a=e.body,r=i.clientTop||a.clientTop||0,n=i.clientLeft||a.clientLeft||0,o=i===t?t.scrollY:i.scrollTop,l=i===t?t.scrollX:i.scrollLeft;return{top:s.top+o-r,left:s.left+l-n}}return null},css:function(e,i){var s;if(1===arguments.length){if("string"!=typeof e){for(s=0;ss-1?[]:e<0?(t=s+e)<0?[]:[this[t]]:[this[e]])},append:function(){for(var t,s=[],a=arguments.length;a--;)s[a]=arguments[a];for(var r=0;r=0;a-=1)this[s].insertBefore(r.childNodes[a],this[s].childNodes[0])}else if(t instanceof i)for(a=0;a0?e?this[0].nextElementSibling&&s(this[0].nextElementSibling).is(e)?new i([this[0].nextElementSibling]):new i([]):this[0].nextElementSibling?new i([this[0].nextElementSibling]):new i([]):new i([])},nextAll:function(e){var t=[],a=this[0];if(!a)return new i([]);for(;a.nextElementSibling;){var r=a.nextElementSibling;e?s(r).is(e)&&t.push(r):t.push(r),a=r}return new i(t)},prev:function(e){if(this.length>0){var t=this[0];return e?t.previousElementSibling&&s(t.previousElementSibling).is(e)?new i([t.previousElementSibling]):new i([]):t.previousElementSibling?new i([t.previousElementSibling]):new i([])}return new i([])},prevAll:function(e){var t=[],a=this[0];if(!a)return new i([]);for(;a.previousElementSibling;){var r=a.previousElementSibling;e?s(r).is(e)&&t.push(r):t.push(r),a=r}return new i(t)},parent:function(e){for(var t=[],i=0;i6&&(a=a.split(", ").map((function(e){return e.replace(",",".")})).join(", ")),r=new t.WebKitCSSMatrix("none"===a?"":a)):s=(r=n.MozTransform||n.OTransform||n.MsTransform||n.msTransform||n.transform||n.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,")).toString().split(","),"x"===i&&(a=t.WebKitCSSMatrix?r.m41:16===s.length?parseFloat(s[12]):parseFloat(s[4])),"y"===i&&(a=t.WebKitCSSMatrix?r.m42:16===s.length?parseFloat(s[13]):parseFloat(s[5])),a||0},parseUrlQuery:function(e){var i,s,a,r,n={},o=e||t.location.href;if("string"==typeof o&&o.length)for(r=(s=(o=o.indexOf("?")>-1?o.replace(/\S*\?/,""):"").split("&").filter((function(e){return""!==e}))).length,i=0;i0||"ontouchstart"in t||t.DocumentTouch&&e instanceof t.DocumentTouch),pointerEvents:!!t.PointerEvent&&"maxTouchPoints"in t.navigator&&t.navigator.maxTouchPoints>0,observer:"MutationObserver"in t||"WebkitMutationObserver"in t,passiveListener:function(){var e=!1;try{var i=Object.defineProperty({},"passive",{get:function(){e=!0}});t.addEventListener("testPassiveListener",null,i)}catch(e){}return e}(),gestures:"ongesturestart"in t},l=function(e){void 0===e&&(e={});var t=this;t.params=e,t.eventsListeners={},t.params&&t.params.on&&Object.keys(t.params.on).forEach((function(e){t.on(e,t.params.on[e])}))},d={components:{configurable:!0}};l.prototype.on=function(e,t,i){var s=this;if("function"!=typeof t)return s;var a=i?"unshift":"push";return e.split(" ").forEach((function(e){s.eventsListeners[e]||(s.eventsListeners[e]=[]),s.eventsListeners[e][a](t)})),s},l.prototype.once=function(e,t,i){var s=this;if("function"!=typeof t)return s;function a(){for(var i=[],r=arguments.length;r--;)i[r]=arguments[r];s.off(e,a),a.f7proxy&&delete a.f7proxy,t.apply(s,i)}return a.f7proxy=t,s.on(e,a,i)},l.prototype.off=function(e,t){var i=this;return i.eventsListeners?(e.split(" ").forEach((function(e){void 0===t?i.eventsListeners[e]=[]:i.eventsListeners[e]&&i.eventsListeners[e].length&&i.eventsListeners[e].forEach((function(s,a){(s===t||s.f7proxy&&s.f7proxy===t)&&i.eventsListeners[e].splice(a,1)}))})),i):i},l.prototype.emit=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];var i,s,a,r=this;if(!r.eventsListeners)return r;"string"==typeof e[0]||Array.isArray(e[0])?(i=e[0],s=e.slice(1,e.length),a=r):(i=e[0].events,s=e[0].data,a=e[0].context||r);var n=Array.isArray(i)?i:i.split(" ");return n.forEach((function(e){if(r.eventsListeners&&r.eventsListeners[e]){var t=[];r.eventsListeners[e].forEach((function(e){t.push(e)})),t.forEach((function(e){e.apply(a,s)}))}})),r},l.prototype.useModulesParams=function(e){var t=this;t.modules&&Object.keys(t.modules).forEach((function(i){var s=t.modules[i];s.params&&n.extend(e,s.params)}))},l.prototype.useModules=function(e){void 0===e&&(e={});var t=this;t.modules&&Object.keys(t.modules).forEach((function(i){var s=t.modules[i],a=e[i]||{};s.instance&&Object.keys(s.instance).forEach((function(e){var i=s.instance[e];t[e]="function"==typeof i?i.bind(t):i})),s.on&&t.on&&Object.keys(s.on).forEach((function(e){t.on(e,s.on[e])})),s.create&&s.create.bind(t)(a)}))},d.components.set=function(e){this.use&&this.use(e)},l.installModule=function(e){for(var t=[],i=arguments.length-1;i-- >0;)t[i]=arguments[i+1];var s=this;s.prototype.modules||(s.prototype.modules={});var a=e.name||Object.keys(s.prototype.modules).length+"_"+n.now();return s.prototype.modules[a]=e,e.proto&&Object.keys(e.proto).forEach((function(t){s.prototype[t]=e.proto[t]})),e.static&&Object.keys(e.static).forEach((function(t){s[t]=e.static[t]})),e.install&&e.install.apply(s,t),s},l.use=function(e){for(var t=[],i=arguments.length-1;i-- >0;)t[i]=arguments[i+1];var s=this;return Array.isArray(e)?(e.forEach((function(e){return s.installModule(e)})),s):s.installModule.apply(s,[e].concat(t))},Object.defineProperties(l,d);var h={updateSize:function(){var e,t,i=this.$el;e=void 0!==this.params.width?this.params.width:i[0].clientWidth,t=void 0!==this.params.height?this.params.height:i[0].clientHeight,0===e&&this.isHorizontal()||0===t&&this.isVertical()||(e=e-parseInt(i.css("padding-left"),10)-parseInt(i.css("padding-right"),10),t=t-parseInt(i.css("padding-top"),10)-parseInt(i.css("padding-bottom"),10),n.extend(this,{width:e,height:t,size:this.isHorizontal()?e:t}))},updateSlides:function(){var e=this.params,i=this.$wrapperEl,s=this.size,a=this.rtlTranslate,r=this.wrongRTL,o=this.virtual&&e.virtual.enabled,l=o?this.virtual.slides.length:this.slides.length,d=i.children("."+this.params.slideClass),h=o?this.virtual.slides.length:d.length,p=[],c=[],u=[];function v(t){return!e.cssMode||t!==d.length-1}var f=e.slidesOffsetBefore;"function"==typeof f&&(f=e.slidesOffsetBefore.call(this));var m=e.slidesOffsetAfter;"function"==typeof m&&(m=e.slidesOffsetAfter.call(this));var g=this.snapGrid.length,b=this.snapGrid.length,w=e.spaceBetween,y=-f,x=0,T=0;if(void 0!==s){var E,S;"string"==typeof w&&w.indexOf("%")>=0&&(w=parseFloat(w.replace("%",""))/100*s),this.virtualSize=-w,a?d.css({marginLeft:"",marginTop:""}):d.css({marginRight:"",marginBottom:""}),e.slidesPerColumn>1&&(E=Math.floor(h/e.slidesPerColumn)===h/this.params.slidesPerColumn?h:Math.ceil(h/e.slidesPerColumn)*e.slidesPerColumn,"auto"!==e.slidesPerView&&"row"===e.slidesPerColumnFill&&(E=Math.max(E,e.slidesPerView*e.slidesPerColumn)));for(var C,M=e.slidesPerColumn,P=E/M,z=Math.floor(h/e.slidesPerColumn),k=0;k1){var L=void 0,I=void 0,D=void 0;if("row"===e.slidesPerColumnFill&&e.slidesPerGroup>1){var O=Math.floor(k/(e.slidesPerGroup*e.slidesPerColumn)),A=k-e.slidesPerColumn*e.slidesPerGroup*O,G=0===O?e.slidesPerGroup:Math.min(Math.ceil((h-O*M*e.slidesPerGroup)/M),e.slidesPerGroup);L=(I=A-(D=Math.floor(A/G))*G+O*e.slidesPerGroup)+D*E/M,$.css({"-webkit-box-ordinal-group":L,"-moz-box-ordinal-group":L,"-ms-flex-order":L,"-webkit-order":L,order:L})}else"column"===e.slidesPerColumnFill?(D=k-(I=Math.floor(k/M))*M,(I>z||I===z&&D===M-1)&&(D+=1)>=M&&(D=0,I+=1)):I=k-(D=Math.floor(k/P))*P;$.css("margin-"+(this.isHorizontal()?"top":"left"),0!==D&&e.spaceBetween&&e.spaceBetween+"px")}if("none"!==$.css("display")){if("auto"===e.slidesPerView){var H=t.getComputedStyle($[0],null),B=$[0].style.transform,N=$[0].style.webkitTransform;if(B&&($[0].style.transform="none"),N&&($[0].style.webkitTransform="none"),e.roundLengths)S=this.isHorizontal()?$.outerWidth(!0):$.outerHeight(!0);else if(this.isHorizontal()){var X=parseFloat(H.getPropertyValue("width")),V=parseFloat(H.getPropertyValue("padding-left")),Y=parseFloat(H.getPropertyValue("padding-right")),F=parseFloat(H.getPropertyValue("margin-left")),W=parseFloat(H.getPropertyValue("margin-right")),R=H.getPropertyValue("box-sizing");S=R&&"border-box"===R?X+F+W:X+V+Y+F+W}else{var q=parseFloat(H.getPropertyValue("height")),j=parseFloat(H.getPropertyValue("padding-top")),K=parseFloat(H.getPropertyValue("padding-bottom")),U=parseFloat(H.getPropertyValue("margin-top")),_=parseFloat(H.getPropertyValue("margin-bottom")),Z=H.getPropertyValue("box-sizing");S=Z&&"border-box"===Z?q+U+_:q+j+K+U+_}B&&($[0].style.transform=B),N&&($[0].style.webkitTransform=N),e.roundLengths&&(S=Math.floor(S))}else S=(s-(e.slidesPerView-1)*w)/e.slidesPerView,e.roundLengths&&(S=Math.floor(S)),d[k]&&(this.isHorizontal()?d[k].style.width=S+"px":d[k].style.height=S+"px");d[k]&&(d[k].swiperSlideSize=S),u.push(S),e.centeredSlides?(y=y+S/2+x/2+w,0===x&&0!==k&&(y=y-s/2-w),0===k&&(y=y-s/2-w),Math.abs(y)<.001&&(y=0),e.roundLengths&&(y=Math.floor(y)),T%e.slidesPerGroup==0&&p.push(y),c.push(y)):(e.roundLengths&&(y=Math.floor(y)),(T-Math.min(this.params.slidesPerGroupSkip,T))%this.params.slidesPerGroup==0&&p.push(y),c.push(y),y=y+S+w),this.virtualSize+=S+w,x=S,T+=1}}if(this.virtualSize=Math.max(this.virtualSize,s)+m,a&&r&&("slide"===e.effect||"coverflow"===e.effect)&&i.css({width:this.virtualSize+e.spaceBetween+"px"}),e.setWrapperSize&&(this.isHorizontal()?i.css({width:this.virtualSize+e.spaceBetween+"px"}):i.css({height:this.virtualSize+e.spaceBetween+"px"})),e.slidesPerColumn>1&&(this.virtualSize=(S+e.spaceBetween)*E,this.virtualSize=Math.ceil(this.virtualSize/e.slidesPerColumn)-e.spaceBetween,this.isHorizontal()?i.css({width:this.virtualSize+e.spaceBetween+"px"}):i.css({height:this.virtualSize+e.spaceBetween+"px"}),e.centeredSlides)){C=[];for(var Q=0;Q1&&p.push(this.virtualSize-s)}if(0===p.length&&(p=[0]),0!==e.spaceBetween&&(this.isHorizontal()?a?d.filter(v).css({marginLeft:w+"px"}):d.filter(v).css({marginRight:w+"px"}):d.filter(v).css({marginBottom:w+"px"})),e.centeredSlides&&e.centeredSlidesBounds){var ie=0;u.forEach((function(t){ie+=t+(e.spaceBetween?e.spaceBetween:0)}));var se=(ie-=e.spaceBetween)-s;p=p.map((function(e){return e<0?-f:e>se?se+m:e}))}if(e.centerInsufficientSlides){var ae=0;if(u.forEach((function(t){ae+=t+(e.spaceBetween?e.spaceBetween:0)})),(ae-=e.spaceBetween)1)if(this.params.centeredSlides)i.push.apply(i,this.visibleSlides);else for(t=0;tthis.slides.length)break;i.push(this.slides.eq(a)[0])}else i.push(this.slides.eq(this.activeIndex)[0]);for(t=0;ts?r:s}s&&this.$wrapperEl.css("height",s+"px")},updateSlidesOffset:function(){for(var e=this.slides,t=0;t=0&&d1&&h<=this.size||d<=0&&h>=this.size)&&(this.visibleSlides.push(o),this.visibleSlidesIndexes.push(n),i.eq(n).addClass(t.slideVisibleClass))}o.progress=a?-l:l}this.visibleSlides=s(this.visibleSlides)}},updateProgress:function(e){if(void 0===e){var t=this.rtlTranslate?-1:1;e=this&&this.translate&&this.translate*t||0}var i=this.params,s=this.maxTranslate()-this.minTranslate(),a=this.progress,r=this.isBeginning,o=this.isEnd,l=r,d=o;0===s?(a=0,r=!0,o=!0):(r=(a=(e-this.minTranslate())/s)<=0,o=a>=1),n.extend(this,{progress:a,isBeginning:r,isEnd:o}),(i.watchSlidesProgress||i.watchSlidesVisibility||i.centeredSlides&&i.autoHeight)&&this.updateSlidesProgress(e),r&&!l&&this.emit("reachBeginning toEdge"),o&&!d&&this.emit("reachEnd toEdge"),(l&&!r||d&&!o)&&this.emit("fromEdge"),this.emit("progress",a)},updateSlidesClasses:function(){var e,t=this.slides,i=this.params,s=this.$wrapperEl,a=this.activeIndex,r=this.realIndex,n=this.virtual&&i.virtual.enabled;t.removeClass(i.slideActiveClass+" "+i.slideNextClass+" "+i.slidePrevClass+" "+i.slideDuplicateActiveClass+" "+i.slideDuplicateNextClass+" "+i.slideDuplicatePrevClass),(e=n?this.$wrapperEl.find("."+i.slideClass+'[data-swiper-slide-index="'+a+'"]'):t.eq(a)).addClass(i.slideActiveClass),i.loop&&(e.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+r+'"]').addClass(i.slideDuplicateActiveClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+r+'"]').addClass(i.slideDuplicateActiveClass));var o=e.nextAll("."+i.slideClass).eq(0).addClass(i.slideNextClass);i.loop&&0===o.length&&(o=t.eq(0)).addClass(i.slideNextClass);var l=e.prevAll("."+i.slideClass).eq(0).addClass(i.slidePrevClass);i.loop&&0===l.length&&(l=t.eq(-1)).addClass(i.slidePrevClass),i.loop&&(o.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+o.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+o.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass),l.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass))},updateActiveIndex:function(e){var t,i=this.rtlTranslate?this.translate:-this.translate,s=this.slidesGrid,a=this.snapGrid,r=this.params,o=this.activeIndex,l=this.realIndex,d=this.snapIndex,h=e;if(void 0===h){for(var p=0;p=s[p]&&i=s[p]&&i=s[p]&&(h=p);r.normalizeSlideIndex&&(h<0||void 0===h)&&(h=0)}if(a.indexOf(i)>=0)t=a.indexOf(i);else{var c=Math.min(r.slidesPerGroupSkip,h);t=c+Math.floor((h-c)/r.slidesPerGroup)}if(t>=a.length&&(t=a.length-1),h!==o){var u=parseInt(this.slides.eq(h).attr("data-swiper-slide-index")||h,10);n.extend(this,{snapIndex:t,realIndex:u,previousIndex:o,activeIndex:h}),this.emit("activeIndexChange"),this.emit("snapIndexChange"),l!==u&&this.emit("realIndexChange"),(this.initialized||this.runCallbacksOnInit)&&this.emit("slideChange")}else t!==d&&(this.snapIndex=t,this.emit("snapIndexChange"))},updateClickedSlide:function(e){var t=this.params,i=s(e.target).closest("."+t.slideClass)[0],a=!1;if(i)for(var r=0;rh?h:s&&ea?"next":is?"next":i=l.length&&(f=l.length-1),(p||o.initialSlide||0)===(h||0)&&i&&r.emit("beforeSlideChangeStart");var m,g=-l[f];if(r.updateProgress(g),o.normalizeSlideIndex)for(var b=0;b=Math.floor(100*d[b])&&(n=b);if(r.initialized&&n!==p){if(!r.allowSlideNext&&gr.translate&&g>r.maxTranslate()&&(p||0)!==n)return!1}if(m=n>p?"next":n=e&&(c=e)})),void 0!==c&&(d=n.indexOf(c))<0&&(d=this.activeIndex-1),this.slideTo(d,e,t,i)},slideReset:function(e,t,i){return void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),this.slideTo(this.activeIndex,e,t,i)},slideToClosest:function(e,t,i,s){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),void 0===s&&(s=.5);var a=this.activeIndex,r=Math.min(this.params.slidesPerGroupSkip,a),n=r+Math.floor((a-r)/this.params.slidesPerGroup),o=this.rtlTranslate?this.translate:-this.translate;if(o>=this.snapGrid[n]){var l=this.snapGrid[n];o-l>(this.snapGrid[n+1]-l)*s&&(a+=this.params.slidesPerGroup)}else{var d=this.snapGrid[n-1];o-d<=(this.snapGrid[n]-d)*s&&(a-=this.params.slidesPerGroup)}return a=Math.max(a,0),a=Math.min(a,this.slidesGrid.length-1),this.slideTo(a,e,t,i)},slideToClickedSlide:function(){var e,t=this,i=t.params,a=t.$wrapperEl,r="auto"===i.slidesPerView?t.slidesPerViewDynamic():i.slidesPerView,o=t.clickedIndex;if(i.loop){if(t.animating)return;e=parseInt(s(t.clickedSlide).attr("data-swiper-slide-index"),10),i.centeredSlides?ot.slides.length-t.loopedSlides+r/2?(t.loopFix(),o=a.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+i.slideDuplicateClass+")").eq(0).index(),n.nextTick((function(){t.slideTo(o)}))):t.slideTo(o):o>t.slides.length-r?(t.loopFix(),o=a.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+i.slideDuplicateClass+")").eq(0).index(),n.nextTick((function(){t.slideTo(o)}))):t.slideTo(o)}else t.slideTo(o)}};var v={loopCreate:function(){var t=this,i=t.params,a=t.$wrapperEl;a.children("."+i.slideClass+"."+i.slideDuplicateClass).remove();var r=a.children("."+i.slideClass);if(i.loopFillGroupWithBlank){var n=i.slidesPerGroup-r.length%i.slidesPerGroup;if(n!==i.slidesPerGroup){for(var o=0;or.length&&(t.loopedSlides=r.length);var d=[],h=[];r.each((function(e,i){var a=s(i);e=r.length-t.loopedSlides&&d.push(i),a.attr("data-swiper-slide-index",e)}));for(var p=0;p=0;c-=1)a.prepend(s(d[c].cloneNode(!0)).addClass(i.slideDuplicateClass))},loopFix:function(){this.emit("beforeLoopFix");var e,t=this.activeIndex,i=this.slides,s=this.loopedSlides,a=this.allowSlidePrev,r=this.allowSlideNext,n=this.snapGrid,o=this.rtlTranslate;this.allowSlidePrev=!0,this.allowSlideNext=!0;var l=-n[t]-this.getTranslate();if(t=i.length-s){e=-i.length+t+s,e+=s,this.slideTo(e,0,!1,!0)&&0!==l&&this.setTranslate((o?-this.translate:this.translate)-l)}this.allowSlidePrev=a,this.allowSlideNext=r,this.emit("loopFix")},loopDestroy:function(){var e=this.$wrapperEl,t=this.params,i=this.slides;e.children("."+t.slideClass+"."+t.slideDuplicateClass+",."+t.slideClass+"."+t.slideBlankClass).remove(),i.removeAttr("data-swiper-slide-index")}};var f={setGrabCursor:function(e){if(!(o.touch||!this.params.simulateTouch||this.params.watchOverflow&&this.isLocked||this.params.cssMode)){var t=this.el;t.style.cursor="move",t.style.cursor=e?"-webkit-grabbing":"-webkit-grab",t.style.cursor=e?"-moz-grabbin":"-moz-grab",t.style.cursor=e?"grabbing":"grab"}},unsetGrabCursor:function(){o.touch||this.params.watchOverflow&&this.isLocked||this.params.cssMode||(this.el.style.cursor="")}};var m,g,b,w,y,x,T,E,S,C,M,P,z,k,$,L={appendSlide:function(e){var t=this.$wrapperEl,i=this.params;if(i.loop&&this.loopDestroy(),"object"==typeof e&&"length"in e)for(var s=0;s=r)this.appendSlide(t);else{for(var n=a>e?a+1:a,l=[],d=r-1;d>=e;d-=1){var h=this.slides.eq(d);h.remove(),l.unshift(h)}if("object"==typeof t&&"length"in t){for(var p=0;pe?a+t.length:a}else i.append(t);for(var c=0;c=0||g.indexOf("Trident/")>=0,M=g.indexOf("Edge/")>=0,P=g.indexOf("Gecko/")>=0&&g.indexOf("Firefox/")>=0,z="Win32"===m,k=g.toLowerCase().indexOf("electron")>=0,$="MacIntel"===m,!T&&$&&o.touch&&(1024===w&&1366===y||834===w&&1194===y||834===w&&1112===y||768===w&&1024===y)&&(T=g.match(/(Version)\/([\d.]+)/),$=!1),b.ie=C,b.edge=M,b.firefox=P,x&&!z&&(b.os="android",b.osVersion=x[2],b.android=!0,b.androidChrome=g.toLowerCase().indexOf("chrome")>=0),(T||S||E)&&(b.os="ios",b.ios=!0),S&&!E&&(b.osVersion=S[2].replace(/_/g,"."),b.iphone=!0),T&&(b.osVersion=T[2].replace(/_/g,"."),b.ipad=!0),E&&(b.osVersion=E[3]?E[3].replace(/_/g,"."):null,b.ipod=!0),b.ios&&b.osVersion&&g.indexOf("Version/")>=0&&"10"===b.osVersion.split(".")[0]&&(b.osVersion=g.toLowerCase().split("version/")[1].split(" ")[0]),b.webView=!(!(S||T||E)||!g.match(/.*AppleWebKit(?!.*Safari)/i)&&!t.navigator.standalone)||t.matchMedia&&t.matchMedia("(display-mode: standalone)").matches,b.webview=b.webView,b.standalone=b.webView,b.desktop=!(b.ios||b.android)||k,b.desktop&&(b.electron=k,b.macos=$,b.windows=z,b.macos&&(b.os="macos"),b.windows&&(b.os="windows")),b.pixelRatio=t.devicePixelRatio||1,b);function D(i){var a=this.touchEventsData,r=this.params,o=this.touches;if(!this.animating||!r.preventInteractionOnTransition){var l=i;l.originalEvent&&(l=l.originalEvent);var d=s(l.target);if(("wrapper"!==r.touchEventsTarget||d.closest(this.wrapperEl).length)&&(a.isTouchEvent="touchstart"===l.type,(a.isTouchEvent||!("which"in l)||3!==l.which)&&!(!a.isTouchEvent&&"button"in l&&l.button>0||a.isTouched&&a.isMoved)))if(r.noSwiping&&d.closest(r.noSwipingSelector?r.noSwipingSelector:"."+r.noSwipingClass)[0])this.allowClick=!0;else if(!r.swipeHandler||d.closest(r.swipeHandler)[0]){o.currentX="touchstart"===l.type?l.targetTouches[0].pageX:l.pageX,o.currentY="touchstart"===l.type?l.targetTouches[0].pageY:l.pageY;var h=o.currentX,p=o.currentY,c=r.edgeSwipeDetection||r.iOSEdgeSwipeDetection,u=r.edgeSwipeThreshold||r.iOSEdgeSwipeThreshold;if(!c||!(h<=u||h>=t.screen.width-u)){if(n.extend(a,{isTouched:!0,isMoved:!1,allowTouchCallbacks:!0,isScrolling:void 0,startMoving:void 0}),o.startX=h,o.startY=p,a.touchStartTime=n.now(),this.allowClick=!0,this.updateSize(),this.swipeDirection=void 0,r.threshold>0&&(a.allowThresholdMove=!1),"touchstart"!==l.type){var v=!0;d.is(a.formElements)&&(v=!1),e.activeElement&&s(e.activeElement).is(a.formElements)&&e.activeElement!==d[0]&&e.activeElement.blur();var f=v&&this.allowTouchMove&&r.touchStartPreventDefault;(r.touchStartForcePreventDefault||f)&&l.preventDefault()}this.emit("touchStart",l)}}}}function O(t){var i=this.touchEventsData,a=this.params,r=this.touches,o=this.rtlTranslate,l=t;if(l.originalEvent&&(l=l.originalEvent),i.isTouched){if(!i.isTouchEvent||"mousemove"!==l.type){var d="touchmove"===l.type&&l.targetTouches&&(l.targetTouches[0]||l.changedTouches[0]),h="touchmove"===l.type?d.pageX:l.pageX,p="touchmove"===l.type?d.pageY:l.pageY;if(l.preventedByNestedSwiper)return r.startX=h,void(r.startY=p);if(!this.allowTouchMove)return this.allowClick=!1,void(i.isTouched&&(n.extend(r,{startX:h,startY:p,currentX:h,currentY:p}),i.touchStartTime=n.now()));if(i.isTouchEvent&&a.touchReleaseOnEdges&&!a.loop)if(this.isVertical()){if(pr.startY&&this.translate>=this.minTranslate())return i.isTouched=!1,void(i.isMoved=!1)}else if(hr.startX&&this.translate>=this.minTranslate())return;if(i.isTouchEvent&&e.activeElement&&l.target===e.activeElement&&s(l.target).is(i.formElements))return i.isMoved=!0,void(this.allowClick=!1);if(i.allowTouchCallbacks&&this.emit("touchMove",l),!(l.targetTouches&&l.targetTouches.length>1)){r.currentX=h,r.currentY=p;var c=r.currentX-r.startX,u=r.currentY-r.startY;if(!(this.params.threshold&&Math.sqrt(Math.pow(c,2)+Math.pow(u,2))=25&&(v=180*Math.atan2(Math.abs(u),Math.abs(c))/Math.PI,i.isScrolling=this.isHorizontal()?v>a.touchAngle:90-v>a.touchAngle);if(i.isScrolling&&this.emit("touchMoveOpposite",l),void 0===i.startMoving&&(r.currentX===r.startX&&r.currentY===r.startY||(i.startMoving=!0)),i.isScrolling)i.isTouched=!1;else if(i.startMoving){this.allowClick=!1,a.cssMode||l.preventDefault(),a.touchMoveStopPropagation&&!a.nested&&l.stopPropagation(),i.isMoved||(a.loop&&this.loopFix(),i.startTranslate=this.getTranslate(),this.setTransition(0),this.animating&&this.$wrapperEl.trigger("webkitTransitionEnd transitionend"),i.allowMomentumBounce=!1,!a.grabCursor||!0!==this.allowSlideNext&&!0!==this.allowSlidePrev||this.setGrabCursor(!0),this.emit("sliderFirstMove",l)),this.emit("sliderMove",l),i.isMoved=!0;var f=this.isHorizontal()?c:u;r.diff=f,f*=a.touchRatio,o&&(f=-f),this.swipeDirection=f>0?"prev":"next",i.currentTranslate=f+i.startTranslate;var m=!0,g=a.resistanceRatio;if(a.touchReleaseOnEdges&&(g=0),f>0&&i.currentTranslate>this.minTranslate()?(m=!1,a.resistance&&(i.currentTranslate=this.minTranslate()-1+Math.pow(-this.minTranslate()+i.startTranslate+f,g))):f<0&&i.currentTranslatei.startTranslate&&(i.currentTranslate=i.startTranslate),a.threshold>0){if(!(Math.abs(f)>a.threshold||i.allowThresholdMove))return void(i.currentTranslate=i.startTranslate);if(!i.allowThresholdMove)return i.allowThresholdMove=!0,r.startX=r.currentX,r.startY=r.currentY,i.currentTranslate=i.startTranslate,void(r.diff=this.isHorizontal()?r.currentX-r.startX:r.currentY-r.startY)}a.followFinger&&!a.cssMode&&((a.freeMode||a.watchSlidesProgress||a.watchSlidesVisibility)&&(this.updateActiveIndex(),this.updateSlidesClasses()),a.freeMode&&(0===i.velocities.length&&i.velocities.push({position:r[this.isHorizontal()?"startX":"startY"],time:i.touchStartTime}),i.velocities.push({position:r[this.isHorizontal()?"currentX":"currentY"],time:n.now()})),this.updateProgress(i.currentTranslate),this.setTranslate(i.currentTranslate))}}}}}else i.startMoving&&i.isScrolling&&this.emit("touchMoveOpposite",l)}function A(e){var t=this,i=t.touchEventsData,s=t.params,a=t.touches,r=t.rtlTranslate,o=t.$wrapperEl,l=t.slidesGrid,d=t.snapGrid,h=e;if(h.originalEvent&&(h=h.originalEvent),i.allowTouchCallbacks&&t.emit("touchEnd",h),i.allowTouchCallbacks=!1,!i.isTouched)return i.isMoved&&s.grabCursor&&t.setGrabCursor(!1),i.isMoved=!1,void(i.startMoving=!1);s.grabCursor&&i.isMoved&&i.isTouched&&(!0===t.allowSlideNext||!0===t.allowSlidePrev)&&t.setGrabCursor(!1);var p,c=n.now(),u=c-i.touchStartTime;if(t.allowClick&&(t.updateClickedSlide(h),t.emit("tap click",h),u<300&&c-i.lastClickTime<300&&t.emit("doubleTap doubleClick",h)),i.lastClickTime=n.now(),n.nextTick((function(){t.destroyed||(t.allowClick=!0)})),!i.isTouched||!i.isMoved||!t.swipeDirection||0===a.diff||i.currentTranslate===i.startTranslate)return i.isTouched=!1,i.isMoved=!1,void(i.startMoving=!1);if(i.isTouched=!1,i.isMoved=!1,i.startMoving=!1,p=s.followFinger?r?t.translate:-t.translate:-i.currentTranslate,!s.cssMode)if(s.freeMode){if(p<-t.minTranslate())return void t.slideTo(t.activeIndex);if(p>-t.maxTranslate())return void(t.slides.length1){var v=i.velocities.pop(),f=i.velocities.pop(),m=v.position-f.position,g=v.time-f.time;t.velocity=m/g,t.velocity/=2,Math.abs(t.velocity)150||n.now()-v.time>300)&&(t.velocity=0)}else t.velocity=0;t.velocity*=s.freeModeMomentumVelocityRatio,i.velocities.length=0;var b=1e3*s.freeModeMomentumRatio,w=t.velocity*b,y=t.translate+w;r&&(y=-y);var x,T,E=!1,S=20*Math.abs(t.velocity)*s.freeModeMomentumBounceRatio;if(yt.minTranslate())s.freeModeMomentumBounce?(y-t.minTranslate()>S&&(y=t.minTranslate()+S),x=t.minTranslate(),E=!0,i.allowMomentumBounce=!0):y=t.minTranslate(),s.loop&&s.centeredSlides&&(T=!0);else if(s.freeModeSticky){for(var C,M=0;M-y){C=M;break}y=-(y=Math.abs(d[C]-y)=s.longSwipesMs)&&(t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses())}else{for(var k=0,$=t.slidesSizesGrid[0],L=0;L=l[L]&&p=l[L]&&(k=L,$=l[l.length-1]-l[l.length-2])}var D=(p-l[k])/$,O=ks.longSwipesMs){if(!s.longSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&(D>=s.longSwipesRatio?t.slideTo(k+O):t.slideTo(k)),"prev"===t.swipeDirection&&(D>1-s.longSwipesRatio?t.slideTo(k+O):t.slideTo(k))}else{if(!s.shortSwipes)return void t.slideTo(t.activeIndex);t.navigation&&(h.target===t.navigation.nextEl||h.target===t.navigation.prevEl)?h.target===t.navigation.nextEl?t.slideTo(k+O):t.slideTo(k):("next"===t.swipeDirection&&t.slideTo(k+O),"prev"===t.swipeDirection&&t.slideTo(k))}}}function G(){var e=this.params,t=this.el;if(!t||0!==t.offsetWidth){e.breakpoints&&this.setBreakpoint();var i=this.allowSlideNext,s=this.allowSlidePrev,a=this.snapGrid;this.allowSlideNext=!0,this.allowSlidePrev=!0,this.updateSize(),this.updateSlides(),this.updateSlidesClasses(),("auto"===e.slidesPerView||e.slidesPerView>1)&&this.isEnd&&!this.params.centeredSlides?this.slideTo(this.slides.length-1,0,!1,!0):this.slideTo(this.activeIndex,0,!1,!0),this.autoplay&&this.autoplay.running&&this.autoplay.paused&&this.autoplay.run(),this.allowSlidePrev=s,this.allowSlideNext=i,this.params.watchOverflow&&a!==this.snapGrid&&this.checkOverflow()}}function H(e){this.allowClick||(this.params.preventClicks&&e.preventDefault(),this.params.preventClicksPropagation&&this.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))}function B(){var e=this.wrapperEl;this.previousTranslate=this.translate,this.translate=this.isHorizontal()?-e.scrollLeft:-e.scrollTop,-0===this.translate&&(this.translate=0),this.updateActiveIndex(),this.updateSlidesClasses();var t=this.maxTranslate()-this.minTranslate();(0===t?0:(this.translate-this.minTranslate())/t)!==this.progress&&this.updateProgress(this.translate),this.emit("setTranslate",this.translate,!1)}var N=!1;function X(){}var V={init:!0,direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,cssMode:!1,updateOnWindowResize:!0,preventInteractionOnTransition:!1,edgeSwipeDetection:!1,edgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",breakpoints:void 0,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,slidesPerGroupSkip:0,centeredSlides:!1,centeredSlidesBounds:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,normalizeSlideIndex:!0,centerInsufficientSlides:!1,watchOverflow:!1,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,allowTouchMove:!0,threshold:0,touchMoveStopPropagation:!1,touchStartPreventDefault:!0,touchStartForcePreventDefault:!1,touchReleaseOnEdges:!1,uniqueNavElements:!0,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,loopFillGroupWithBlank:!1,allowSlidePrev:!0,allowSlideNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",noSwipingSelector:null,passiveListeners:!0,containerModifierClass:"swiper-container-",slideClass:"swiper-slide",slideBlankClass:"swiper-slide-invisible-blank",slideActiveClass:"swiper-slide-active",slideDuplicateActiveClass:"swiper-slide-duplicate-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slideDuplicateNextClass:"swiper-slide-duplicate-next",slidePrevClass:"swiper-slide-prev",slideDuplicatePrevClass:"swiper-slide-duplicate-prev",wrapperClass:"swiper-wrapper",runCallbacksOnInit:!0},Y={update:h,translate:p,transition:c,slide:u,loop:v,grabCursor:f,manipulation:L,events:{attachEvents:function(){var t=this.params,i=this.touchEvents,s=this.el,a=this.wrapperEl;this.onTouchStart=D.bind(this),this.onTouchMove=O.bind(this),this.onTouchEnd=A.bind(this),t.cssMode&&(this.onScroll=B.bind(this)),this.onClick=H.bind(this);var r=!!t.nested;if(!o.touch&&o.pointerEvents)s.addEventListener(i.start,this.onTouchStart,!1),e.addEventListener(i.move,this.onTouchMove,r),e.addEventListener(i.end,this.onTouchEnd,!1);else{if(o.touch){var n=!("touchstart"!==i.start||!o.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};s.addEventListener(i.start,this.onTouchStart,n),s.addEventListener(i.move,this.onTouchMove,o.passiveListener?{passive:!1,capture:r}:r),s.addEventListener(i.end,this.onTouchEnd,n),i.cancel&&s.addEventListener(i.cancel,this.onTouchEnd,n),N||(e.addEventListener("touchstart",X),N=!0)}(t.simulateTouch&&!I.ios&&!I.android||t.simulateTouch&&!o.touch&&I.ios)&&(s.addEventListener("mousedown",this.onTouchStart,!1),e.addEventListener("mousemove",this.onTouchMove,r),e.addEventListener("mouseup",this.onTouchEnd,!1))}(t.preventClicks||t.preventClicksPropagation)&&s.addEventListener("click",this.onClick,!0),t.cssMode&&a.addEventListener("scroll",this.onScroll),t.updateOnWindowResize?this.on(I.ios||I.android?"resize orientationchange observerUpdate":"resize observerUpdate",G,!0):this.on("observerUpdate",G,!0)},detachEvents:function(){var t=this.params,i=this.touchEvents,s=this.el,a=this.wrapperEl,r=!!t.nested;if(!o.touch&&o.pointerEvents)s.removeEventListener(i.start,this.onTouchStart,!1),e.removeEventListener(i.move,this.onTouchMove,r),e.removeEventListener(i.end,this.onTouchEnd,!1);else{if(o.touch){var n=!("onTouchStart"!==i.start||!o.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};s.removeEventListener(i.start,this.onTouchStart,n),s.removeEventListener(i.move,this.onTouchMove,r),s.removeEventListener(i.end,this.onTouchEnd,n),i.cancel&&s.removeEventListener(i.cancel,this.onTouchEnd,n)}(t.simulateTouch&&!I.ios&&!I.android||t.simulateTouch&&!o.touch&&I.ios)&&(s.removeEventListener("mousedown",this.onTouchStart,!1),e.removeEventListener("mousemove",this.onTouchMove,r),e.removeEventListener("mouseup",this.onTouchEnd,!1))}(t.preventClicks||t.preventClicksPropagation)&&s.removeEventListener("click",this.onClick,!0),t.cssMode&&a.removeEventListener("scroll",this.onScroll),this.off(I.ios||I.android?"resize orientationchange observerUpdate":"resize observerUpdate",G)}},breakpoints:{setBreakpoint:function(){var e=this.activeIndex,t=this.initialized,i=this.loopedSlides;void 0===i&&(i=0);var s=this.params,a=this.$el,r=s.breakpoints;if(r&&(!r||0!==Object.keys(r).length)){var o=this.getBreakpoint(r);if(o&&this.currentBreakpoint!==o){var l=o in r?r[o]:void 0;l&&["slidesPerView","spaceBetween","slidesPerGroup","slidesPerGroupSkip","slidesPerColumn"].forEach((function(e){var t=l[e];void 0!==t&&(l[e]="slidesPerView"!==e||"AUTO"!==t&&"auto"!==t?"slidesPerView"===e?parseFloat(t):parseInt(t,10):"auto")}));var d=l||this.originalParams,h=s.slidesPerColumn>1,p=d.slidesPerColumn>1;h&&!p?a.removeClass(s.containerModifierClass+"multirow "+s.containerModifierClass+"multirow-column"):!h&&p&&(a.addClass(s.containerModifierClass+"multirow"),"column"===d.slidesPerColumnFill&&a.addClass(s.containerModifierClass+"multirow-column"));var c=d.direction&&d.direction!==s.direction,u=s.loop&&(d.slidesPerView!==s.slidesPerView||c);c&&t&&this.changeDirection(),n.extend(this.params,d),n.extend(this,{allowTouchMove:this.params.allowTouchMove,allowSlideNext:this.params.allowSlideNext,allowSlidePrev:this.params.allowSlidePrev}),this.currentBreakpoint=o,u&&t&&(this.loopDestroy(),this.loopCreate(),this.updateSlides(),this.slideTo(e-i+this.loopedSlides,0,!1)),this.emit("breakpoint",d)}}},getBreakpoint:function(e){if(e){var i=!1,s=Object.keys(e).map((function(e){if("string"==typeof e&&0===e.indexOf("@")){var i=parseFloat(e.substr(1));return{value:t.innerHeight*i,point:e}}return{value:e,point:e}}));s.sort((function(e,t){return parseInt(e.value,10)-parseInt(t.value,10)}));for(var a=0;a0&&e.slidesOffsetBefore+e.spaceBetween*(this.slides.length-1)+this.slides[0].offsetWidth*this.slides.length;e.slidesOffsetBefore&&e.slidesOffsetAfter&&i?this.isLocked=i<=this.size:this.isLocked=1===this.snapGrid.length,this.allowSlideNext=!this.isLocked,this.allowSlidePrev=!this.isLocked,t!==this.isLocked&&this.emit(this.isLocked?"lock":"unlock"),t&&t!==this.isLocked&&(this.isEnd=!1,this.navigation.update())}},classes:{addClasses:function(){var e=this.classNames,t=this.params,i=this.rtl,s=this.$el,a=[];a.push("initialized"),a.push(t.direction),t.freeMode&&a.push("free-mode"),t.autoHeight&&a.push("autoheight"),i&&a.push("rtl"),t.slidesPerColumn>1&&(a.push("multirow"),"column"===t.slidesPerColumnFill&&a.push("multirow-column")),I.android&&a.push("android"),I.ios&&a.push("ios"),t.cssMode&&a.push("css-mode"),a.forEach((function(i){e.push(t.containerModifierClass+i)})),s.addClass(e.join(" "))},removeClasses:function(){var e=this.$el,t=this.classNames;e.removeClass(t.join(" "))}},images:{loadImage:function(e,i,s,a,r,n){var o;function l(){n&&n()}e.complete&&r?l():i?((o=new t.Image).onload=l,o.onerror=l,a&&(o.sizes=a),s&&(o.srcset=s),i&&(o.src=i)):l()},preloadImages:function(){var e=this;function t(){null!=e&&e&&!e.destroyed&&(void 0!==e.imagesLoaded&&(e.imagesLoaded+=1),e.imagesLoaded===e.imagesToLoad.length&&(e.params.updateOnImagesReady&&e.update(),e.emit("imagesReady")))}e.imagesToLoad=e.$el.find("img");for(var i=0;i1){var u=[];return c.each((function(e,i){var s=n.extend({},r,{el:i});u.push(new t(s))})),u}var v,f,m;return a.swiper=h,c.data("swiper",h),a&&a.shadowRoot&&a.shadowRoot.querySelector?(v=s(a.shadowRoot.querySelector("."+h.params.wrapperClass))).children=function(e){return c.children(e)}:v=c.children("."+h.params.wrapperClass),n.extend(h,{$el:c,el:a,$wrapperEl:v,wrapperEl:v[0],classNames:[],slides:s(),slidesGrid:[],snapGrid:[],slidesSizesGrid:[],isHorizontal:function(){return"horizontal"===h.params.direction},isVertical:function(){return"vertical"===h.params.direction},rtl:"rtl"===a.dir.toLowerCase()||"rtl"===c.css("direction"),rtlTranslate:"horizontal"===h.params.direction&&("rtl"===a.dir.toLowerCase()||"rtl"===c.css("direction")),wrongRTL:"-webkit-box"===v.css("display"),activeIndex:0,realIndex:0,isBeginning:!0,isEnd:!1,translate:0,previousTranslate:0,progress:0,velocity:0,animating:!1,allowSlideNext:h.params.allowSlideNext,allowSlidePrev:h.params.allowSlidePrev,touchEvents:(f=["touchstart","touchmove","touchend","touchcancel"],m=["mousedown","mousemove","mouseup"],o.pointerEvents&&(m=["pointerdown","pointermove","pointerup"]),h.touchEventsTouch={start:f[0],move:f[1],end:f[2],cancel:f[3]},h.touchEventsDesktop={start:m[0],move:m[1],end:m[2]},o.touch||!h.params.simulateTouch?h.touchEventsTouch:h.touchEventsDesktop),touchEventsData:{isTouched:void 0,isMoved:void 0,allowTouchCallbacks:void 0,touchStartTime:void 0,isScrolling:void 0,currentTranslate:void 0,startTranslate:void 0,allowThresholdMove:void 0,formElements:"input, select, option, textarea, button, video, label",lastClickTime:n.now(),clickTimeout:void 0,velocities:[],allowMomentumBounce:void 0,isTouchEvent:void 0,startMoving:void 0},allowClick:!0,allowTouchMove:h.params.allowTouchMove,touches:{startX:0,startY:0,currentX:0,currentY:0,diff:0},imagesToLoad:[],imagesLoaded:0}),h.useModules(),h.params.init&&h.init(),h}}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var i={extendedDefaults:{configurable:!0},defaults:{configurable:!0},Class:{configurable:!0},$:{configurable:!0}};return t.prototype.slidesPerViewDynamic=function(){var e=this.params,t=this.slides,i=this.slidesGrid,s=this.size,a=this.activeIndex,r=1;if(e.centeredSlides){for(var n,o=t[a].swiperSlideSize,l=a+1;ls&&(n=!0));for(var d=a-1;d>=0;d-=1)t[d]&&!n&&(r+=1,(o+=t[d].swiperSlideSize)>s&&(n=!0))}else for(var h=a+1;h1)&&e.isEnd&&!e.params.centeredSlides?e.slideTo(e.slides.length-1,0,!1,!0):e.slideTo(e.activeIndex,0,!1,!0))||s(),i.watchOverflow&&t!==e.snapGrid&&e.checkOverflow(),e.emit("update")}function s(){var t=e.rtlTranslate?-1*e.translate:e.translate,i=Math.min(Math.max(t,e.maxTranslate()),e.minTranslate());e.setTranslate(i),e.updateActiveIndex(),e.updateSlidesClasses()}},t.prototype.changeDirection=function(e,t){void 0===t&&(t=!0);var i=this.params.direction;return e||(e="horizontal"===i?"vertical":"horizontal"),e===i||"horizontal"!==e&&"vertical"!==e?this:(this.$el.removeClass(""+this.params.containerModifierClass+i).addClass(""+this.params.containerModifierClass+e),this.params.direction=e,this.slides.each((function(t,i){"vertical"===e?i.style.width="":i.style.height=""})),this.emit("changeDirection"),t&&this.update(),this)},t.prototype.init=function(){this.initialized||(this.emit("beforeInit"),this.params.breakpoints&&this.setBreakpoint(),this.addClasses(),this.params.loop&&this.loopCreate(),this.updateSize(),this.updateSlides(),this.params.watchOverflow&&this.checkOverflow(),this.params.grabCursor&&this.setGrabCursor(),this.params.preloadImages&&this.preloadImages(),this.params.loop?this.slideTo(this.params.initialSlide+this.loopedSlides,0,this.params.runCallbacksOnInit):this.slideTo(this.params.initialSlide,0,this.params.runCallbacksOnInit),this.attachEvents(),this.initialized=!0,this.emit("init"))},t.prototype.destroy=function(e,t){void 0===e&&(e=!0),void 0===t&&(t=!0);var i=this,s=i.params,a=i.$el,r=i.$wrapperEl,o=i.slides;return void 0===i.params||i.destroyed?null:(i.emit("beforeDestroy"),i.initialized=!1,i.detachEvents(),s.loop&&i.loopDestroy(),t&&(i.removeClasses(),a.removeAttr("style"),r.removeAttr("style"),o&&o.length&&o.removeClass([s.slideVisibleClass,s.slideActiveClass,s.slideNextClass,s.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-slide-index")),i.emit("destroy"),Object.keys(i.eventsListeners).forEach((function(e){i.off(e)})),!1!==e&&(i.$el[0].swiper=null,i.$el.data("swiper",null),n.deleteProps(i)),i.destroyed=!0,null)},t.extendDefaults=function(e){n.extend(F,e)},i.extendedDefaults.get=function(){return F},i.defaults.get=function(){return V},i.Class.get=function(){return e},i.$.get=function(){return s},Object.defineProperties(t,i),t}(l),R={name:"device",proto:{device:I},static:{device:I}},q={name:"support",proto:{support:o},static:{support:o}},j={isEdge:!!t.navigator.userAgent.match(/Edge/g),isSafari:function(){var e=t.navigator.userAgent.toLowerCase();return e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0}(),isUiWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(t.navigator.userAgent)},K={name:"browser",proto:{browser:j},static:{browser:j}},U={name:"resize",create:function(){var e=this;n.extend(e,{resize:{resizeHandler:function(){e&&!e.destroyed&&e.initialized&&(e.emit("beforeResize"),e.emit("resize"))},orientationChangeHandler:function(){e&&!e.destroyed&&e.initialized&&e.emit("orientationchange")}}})},on:{init:function(){t.addEventListener("resize",this.resize.resizeHandler),t.addEventListener("orientationchange",this.resize.orientationChangeHandler)},destroy:function(){t.removeEventListener("resize",this.resize.resizeHandler),t.removeEventListener("orientationchange",this.resize.orientationChangeHandler)}}},_={func:t.MutationObserver||t.WebkitMutationObserver,attach:function(e,i){void 0===i&&(i={});var s=this,a=new(0,_.func)((function(e){if(1!==e.length){var i=function(){s.emit("observerUpdate",e[0])};t.requestAnimationFrame?t.requestAnimationFrame(i):t.setTimeout(i,0)}else s.emit("observerUpdate",e[0])}));a.observe(e,{attributes:void 0===i.attributes||i.attributes,childList:void 0===i.childList||i.childList,characterData:void 0===i.characterData||i.characterData}),s.observer.observers.push(a)},init:function(){if(o.observer&&this.params.observer){if(this.params.observeParents)for(var e=this.$el.parents(),t=0;tT)&&t.$wrapperEl.find("."+t.params.slideClass+'[data-swiper-slide-index="'+P+'"]').remove();for(var z=0;z=x&&z<=T&&(void 0===c||e?M.push(z):(z>c&&M.push(z),z'+e+"");return a.attr("data-swiper-slide-index")||a.attr("data-swiper-slide-index",t),i.cache&&(this.virtual.cache[t]=a),a},appendSlide:function(e){if("object"==typeof e&&"length"in e)for(var t=0;t=0;i-=1)this.virtual.slides.splice(e[i],1),this.params.virtual.cache&&delete this.virtual.cache[e[i]],e[i]0&&0===this.$el.parents("."+this.params.slideActiveClass).length)return;var o=t.innerWidth,l=t.innerHeight,d=this.$el.offset();s&&(d.left-=this.$el[0].scrollLeft);for(var h=[[d.left,d.top],[d.left+this.width,d.top],[d.left,d.top+this.height],[d.left+this.width,d.top+this.height]],p=0;p=0&&c[0]<=o&&c[1]>=0&&c[1]<=l&&(n=!0)}if(!n)return}this.isHorizontal()?(33!==r&&34!==r&&37!==r&&39!==r||(a.preventDefault?a.preventDefault():a.returnValue=!1),(34!==r&&39!==r||s)&&(33!==r&&37!==r||!s)||this.slideNext(),(33!==r&&37!==r||s)&&(34!==r&&39!==r||!s)||this.slidePrev()):(33!==r&&34!==r&&38!==r&&40!==r||(a.preventDefault?a.preventDefault():a.returnValue=!1),34!==r&&40!==r||this.slideNext(),33!==r&&38!==r||this.slidePrev()),this.emit("keyPress",r)}},enable:function(){this.keyboard.enabled||(s(e).on("keydown",this.keyboard.handle),this.keyboard.enabled=!0)},disable:function(){this.keyboard.enabled&&(s(e).off("keydown",this.keyboard.handle),this.keyboard.enabled=!1)}},te={name:"keyboard",params:{keyboard:{enabled:!1,onlyInViewport:!0}},create:function(){n.extend(this,{keyboard:{enabled:!1,enable:ee.enable.bind(this),disable:ee.disable.bind(this),handle:ee.handle.bind(this)}})},on:{init:function(){this.params.keyboard.enabled&&this.keyboard.enable()},destroy:function(){this.keyboard.enabled&&this.keyboard.disable()}}};var ie={lastScrollTime:n.now(),lastEventBeforeSnap:void 0,recentWheelEvents:[],event:function(){return t.navigator.userAgent.indexOf("firefox")>-1?"DOMMouseScroll":function(){var t="onwheel"in e;if(!t){var i=e.createElement("div");i.setAttribute("onwheel","return;"),t="function"==typeof i.onwheel}return!t&&e.implementation&&e.implementation.hasFeature&&!0!==e.implementation.hasFeature("","")&&(t=e.implementation.hasFeature("Events.wheel","3.0")),t}()?"wheel":"mousewheel"},normalize:function(e){var t=0,i=0,s=0,a=0;return"detail"in e&&(i=e.detail),"wheelDelta"in e&&(i=-e.wheelDelta/120),"wheelDeltaY"in e&&(i=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=i,i=0),s=10*t,a=10*i,"deltaY"in e&&(a=e.deltaY),"deltaX"in e&&(s=e.deltaX),e.shiftKey&&!s&&(s=a,a=0),(s||a)&&e.deltaMode&&(1===e.deltaMode?(s*=40,a*=40):(s*=800,a*=800)),s&&!t&&(t=s<1?-1:1),a&&!i&&(i=a<1?-1:1),{spinX:t,spinY:i,pixelX:s,pixelY:a}},handleMouseEnter:function(){this.mouseEntered=!0},handleMouseLeave:function(){this.mouseEntered=!1},handle:function(e){var t=e,i=this,a=i.params.mousewheel;i.params.cssMode&&t.preventDefault();var r=i.$el;if("container"!==i.params.mousewheel.eventsTarged&&(r=s(i.params.mousewheel.eventsTarged)),!i.mouseEntered&&!r[0].contains(t.target)&&!a.releaseOnEdges)return!0;t.originalEvent&&(t=t.originalEvent);var o=0,l=i.rtlTranslate?-1:1,d=ie.normalize(t);if(a.forceToAxis)if(i.isHorizontal()){if(!(Math.abs(d.pixelX)>Math.abs(d.pixelY)))return!0;o=d.pixelX*l}else{if(!(Math.abs(d.pixelY)>Math.abs(d.pixelX)))return!0;o=d.pixelY}else o=Math.abs(d.pixelX)>Math.abs(d.pixelY)?-d.pixelX*l:-d.pixelY;if(0===o)return!0;if(a.invert&&(o=-o),i.params.freeMode){var h={time:n.now(),delta:Math.abs(o),direction:Math.sign(o)},p=i.mousewheel.lastEventBeforeSnap,c=p&&h.time=i.minTranslate()&&(u=i.minTranslate()),u<=i.maxTranslate()&&(u=i.maxTranslate()),i.setTransition(0),i.setTranslate(u),i.updateProgress(),i.updateActiveIndex(),i.updateSlidesClasses(),(!v&&i.isBeginning||!f&&i.isEnd)&&i.updateSlidesClasses(),i.params.freeModeSticky){clearTimeout(i.mousewheel.timeout),i.mousewheel.timeout=void 0;var m=i.mousewheel.recentWheelEvents;m.length>=15&&m.shift();var g=m.length?m[m.length-1]:void 0,b=m[0];if(m.push(h),g&&(h.delta>g.delta||h.direction!==g.direction))m.splice(0);else if(m.length>=15&&h.time-b.time<500&&b.delta-h.delta>=1&&h.delta<=6){var w=o>0?.8:.2;i.mousewheel.lastEventBeforeSnap=h,m.splice(0),i.mousewheel.timeout=n.nextTick((function(){i.slideToClosest(i.params.speed,!0,void 0,w)}),0)}i.mousewheel.timeout||(i.mousewheel.timeout=n.nextTick((function(){i.mousewheel.lastEventBeforeSnap=h,m.splice(0),i.slideToClosest(i.params.speed,!0,void 0,.5)}),500))}if(c||i.emit("scroll",t),i.params.autoplay&&i.params.autoplayDisableOnInteraction&&i.autoplay.stop(),u===i.minTranslate()||u===i.maxTranslate())return!0}}else{var y={time:n.now(),delta:Math.abs(o),direction:Math.sign(o),raw:e},x=i.mousewheel.recentWheelEvents;x.length>=2&&x.shift();var T=x.length?x[x.length-1]:void 0;if(x.push(y),T?(y.direction!==T.direction||y.delta>T.delta)&&i.mousewheel.animateSlider(y):i.mousewheel.animateSlider(y),i.mousewheel.releaseScroll(y))return!0}return t.preventDefault?t.preventDefault():t.returnValue=!1,!1},animateSlider:function(e){return e.delta>=6&&n.now()-this.mousewheel.lastScrollTime<60||(e.direction<0?this.isEnd&&!this.params.loop||this.animating||(this.slideNext(),this.emit("scroll",e.raw)):this.isBeginning&&!this.params.loop||this.animating||(this.slidePrev(),this.emit("scroll",e.raw)),this.mousewheel.lastScrollTime=(new t.Date).getTime(),!1)},releaseScroll:function(e){var t=this.params.mousewheel;if(e.direction<0){if(this.isEnd&&!this.params.loop&&t.releaseOnEdges)return!0}else if(this.isBeginning&&!this.params.loop&&t.releaseOnEdges)return!0;return!1},enable:function(){var e=ie.event();if(this.params.cssMode)return this.wrapperEl.removeEventListener(e,this.mousewheel.handle),!0;if(!e)return!1;if(this.mousewheel.enabled)return!1;var t=this.$el;return"container"!==this.params.mousewheel.eventsTarged&&(t=s(this.params.mousewheel.eventsTarged)),t.on("mouseenter",this.mousewheel.handleMouseEnter),t.on("mouseleave",this.mousewheel.handleMouseLeave),t.on(e,this.mousewheel.handle),this.mousewheel.enabled=!0,!0},disable:function(){var e=ie.event();if(this.params.cssMode)return this.wrapperEl.addEventListener(e,this.mousewheel.handle),!0;if(!e)return!1;if(!this.mousewheel.enabled)return!1;var t=this.$el;return"container"!==this.params.mousewheel.eventsTarged&&(t=s(this.params.mousewheel.eventsTarged)),t.off(e,this.mousewheel.handle),this.mousewheel.enabled=!1,!0}},se={update:function(){var e=this.params.navigation;if(!this.params.loop){var t=this.navigation,i=t.$nextEl,s=t.$prevEl;s&&s.length>0&&(this.isBeginning?s.addClass(e.disabledClass):s.removeClass(e.disabledClass),s[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](e.lockClass)),i&&i.length>0&&(this.isEnd?i.addClass(e.disabledClass):i.removeClass(e.disabledClass),i[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](e.lockClass))}},onPrevClick:function(e){e.preventDefault(),this.isBeginning&&!this.params.loop||this.slidePrev()},onNextClick:function(e){e.preventDefault(),this.isEnd&&!this.params.loop||this.slideNext()},init:function(){var e,t,i=this.params.navigation;(i.nextEl||i.prevEl)&&(i.nextEl&&(e=s(i.nextEl),this.params.uniqueNavElements&&"string"==typeof i.nextEl&&e.length>1&&1===this.$el.find(i.nextEl).length&&(e=this.$el.find(i.nextEl))),i.prevEl&&(t=s(i.prevEl),this.params.uniqueNavElements&&"string"==typeof i.prevEl&&t.length>1&&1===this.$el.find(i.prevEl).length&&(t=this.$el.find(i.prevEl))),e&&e.length>0&&e.on("click",this.navigation.onNextClick),t&&t.length>0&&t.on("click",this.navigation.onPrevClick),n.extend(this.navigation,{$nextEl:e,nextEl:e&&e[0],$prevEl:t,prevEl:t&&t[0]}))},destroy:function(){var e=this.navigation,t=e.$nextEl,i=e.$prevEl;t&&t.length&&(t.off("click",this.navigation.onNextClick),t.removeClass(this.params.navigation.disabledClass)),i&&i.length&&(i.off("click",this.navigation.onPrevClick),i.removeClass(this.params.navigation.disabledClass))}},ae={update:function(){var e=this.rtl,t=this.params.pagination;if(t.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var i,a=this.virtual&&this.params.virtual.enabled?this.virtual.slides.length:this.slides.length,r=this.pagination.$el,n=this.params.loop?Math.ceil((a-2*this.loopedSlides)/this.params.slidesPerGroup):this.snapGrid.length;if(this.params.loop?((i=Math.ceil((this.activeIndex-this.loopedSlides)/this.params.slidesPerGroup))>a-1-2*this.loopedSlides&&(i-=a-2*this.loopedSlides),i>n-1&&(i-=n),i<0&&"bullets"!==this.params.paginationType&&(i=n+i)):i=void 0!==this.snapIndex?this.snapIndex:this.activeIndex||0,"bullets"===t.type&&this.pagination.bullets&&this.pagination.bullets.length>0){var o,l,d,h=this.pagination.bullets;if(t.dynamicBullets&&(this.pagination.bulletSize=h.eq(0)[this.isHorizontal()?"outerWidth":"outerHeight"](!0),r.css(this.isHorizontal()?"width":"height",this.pagination.bulletSize*(t.dynamicMainBullets+4)+"px"),t.dynamicMainBullets>1&&void 0!==this.previousIndex&&(this.pagination.dynamicBulletIndex+=i-this.previousIndex,this.pagination.dynamicBulletIndex>t.dynamicMainBullets-1?this.pagination.dynamicBulletIndex=t.dynamicMainBullets-1:this.pagination.dynamicBulletIndex<0&&(this.pagination.dynamicBulletIndex=0)),o=i-this.pagination.dynamicBulletIndex,d=((l=o+(Math.min(h.length,t.dynamicMainBullets)-1))+o)/2),h.removeClass(t.bulletActiveClass+" "+t.bulletActiveClass+"-next "+t.bulletActiveClass+"-next-next "+t.bulletActiveClass+"-prev "+t.bulletActiveClass+"-prev-prev "+t.bulletActiveClass+"-main"),r.length>1)h.each((function(e,a){var r=s(a),n=r.index();n===i&&r.addClass(t.bulletActiveClass),t.dynamicBullets&&(n>=o&&n<=l&&r.addClass(t.bulletActiveClass+"-main"),n===o&&r.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),n===l&&r.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next"))}));else{var p=h.eq(i),c=p.index();if(p.addClass(t.bulletActiveClass),t.dynamicBullets){for(var u=h.eq(o),v=h.eq(l),f=o;f<=l;f+=1)h.eq(f).addClass(t.bulletActiveClass+"-main");if(this.params.loop)if(c>=h.length-t.dynamicMainBullets){for(var m=t.dynamicMainBullets;m>=0;m-=1)h.eq(h.length-m).addClass(t.bulletActiveClass+"-main");h.eq(h.length-t.dynamicMainBullets-1).addClass(t.bulletActiveClass+"-prev")}else u.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),v.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next");else u.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),v.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next")}}if(t.dynamicBullets){var g=Math.min(h.length,t.dynamicMainBullets+4),b=(this.pagination.bulletSize*g-this.pagination.bulletSize)/2-d*this.pagination.bulletSize,w=e?"right":"left";h.css(this.isHorizontal()?w:"top",b+"px")}}if("fraction"===t.type&&(r.find("."+t.currentClass).text(t.formatFractionCurrent(i+1)),r.find("."+t.totalClass).text(t.formatFractionTotal(n))),"progressbar"===t.type){var y;y=t.progressbarOpposite?this.isHorizontal()?"vertical":"horizontal":this.isHorizontal()?"horizontal":"vertical";var x=(i+1)/n,T=1,E=1;"horizontal"===y?T=x:E=x,r.find("."+t.progressbarFillClass).transform("translate3d(0,0,0) scaleX("+T+") scaleY("+E+")").transition(this.params.speed)}"custom"===t.type&&t.renderCustom?(r.html(t.renderCustom(this,i+1,n)),this.emit("paginationRender",this,r[0])):this.emit("paginationUpdate",this,r[0]),r[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](t.lockClass)}},render:function(){var e=this.params.pagination;if(e.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var t=this.virtual&&this.params.virtual.enabled?this.virtual.slides.length:this.slides.length,i=this.pagination.$el,s="";if("bullets"===e.type){for(var a=this.params.loop?Math.ceil((t-2*this.loopedSlides)/this.params.slidesPerGroup):this.snapGrid.length,r=0;r";i.html(s),this.pagination.bullets=i.find("."+e.bulletClass)}"fraction"===e.type&&(s=e.renderFraction?e.renderFraction.call(this,e.currentClass,e.totalClass):' / ',i.html(s)),"progressbar"===e.type&&(s=e.renderProgressbar?e.renderProgressbar.call(this,e.progressbarFillClass):'',i.html(s)),"custom"!==e.type&&this.emit("paginationRender",this.pagination.$el[0])}},init:function(){var e=this,t=e.params.pagination;if(t.el){var i=s(t.el);0!==i.length&&(e.params.uniqueNavElements&&"string"==typeof t.el&&i.length>1&&1===e.$el.find(t.el).length&&(i=e.$el.find(t.el)),"bullets"===t.type&&t.clickable&&i.addClass(t.clickableClass),i.addClass(t.modifierClass+t.type),"bullets"===t.type&&t.dynamicBullets&&(i.addClass(""+t.modifierClass+t.type+"-dynamic"),e.pagination.dynamicBulletIndex=0,t.dynamicMainBullets<1&&(t.dynamicMainBullets=1)),"progressbar"===t.type&&t.progressbarOpposite&&i.addClass(t.progressbarOppositeClass),t.clickable&&i.on("click","."+t.bulletClass,(function(t){t.preventDefault();var i=s(this).index()*e.params.slidesPerGroup;e.params.loop&&(i+=e.loopedSlides),e.slideTo(i)})),n.extend(e.pagination,{$el:i,el:i[0]}))}},destroy:function(){var e=this.params.pagination;if(e.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var t=this.pagination.$el;t.removeClass(e.hiddenClass),t.removeClass(e.modifierClass+e.type),this.pagination.bullets&&this.pagination.bullets.removeClass(e.bulletActiveClass),e.clickable&&t.off("click","."+e.bulletClass)}}},re={setTranslate:function(){if(this.params.scrollbar.el&&this.scrollbar.el){var e=this.scrollbar,t=this.rtlTranslate,i=this.progress,s=e.dragSize,a=e.trackSize,r=e.$dragEl,n=e.$el,o=this.params.scrollbar,l=s,d=(a-s)*i;t?(d=-d)>0?(l=s-d,d=0):-d+s>a&&(l=a+d):d<0?(l=s+d,d=0):d+s>a&&(l=a-d),this.isHorizontal()?(r.transform("translate3d("+d+"px, 0, 0)"),r[0].style.width=l+"px"):(r.transform("translate3d(0px, "+d+"px, 0)"),r[0].style.height=l+"px"),o.hide&&(clearTimeout(this.scrollbar.timeout),n[0].style.opacity=1,this.scrollbar.timeout=setTimeout((function(){n[0].style.opacity=0,n.transition(400)}),1e3))}},setTransition:function(e){this.params.scrollbar.el&&this.scrollbar.el&&this.scrollbar.$dragEl.transition(e)},updateSize:function(){if(this.params.scrollbar.el&&this.scrollbar.el){var e=this.scrollbar,t=e.$dragEl,i=e.$el;t[0].style.width="",t[0].style.height="";var s,a=this.isHorizontal()?i[0].offsetWidth:i[0].offsetHeight,r=this.size/this.virtualSize,o=r*(a/this.size);s="auto"===this.params.scrollbar.dragSize?a*r:parseInt(this.params.scrollbar.dragSize,10),this.isHorizontal()?t[0].style.width=s+"px":t[0].style.height=s+"px",i[0].style.display=r>=1?"none":"",this.params.scrollbar.hide&&(i[0].style.opacity=0),n.extend(e,{trackSize:a,divider:r,moveDivider:o,dragSize:s}),e.$el[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](this.params.scrollbar.lockClass)}},getPointerPosition:function(e){return this.isHorizontal()?"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientX:e.clientX:"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientY:e.clientY},setDragPosition:function(e){var t,i=this.scrollbar,s=this.rtlTranslate,a=i.$el,r=i.dragSize,n=i.trackSize,o=i.dragStartPos;t=(i.getPointerPosition(e)-a.offset()[this.isHorizontal()?"left":"top"]-(null!==o?o:r/2))/(n-r),t=Math.max(Math.min(t,1),0),s&&(t=1-t);var l=this.minTranslate()+(this.maxTranslate()-this.minTranslate())*t;this.updateProgress(l),this.setTranslate(l),this.updateActiveIndex(),this.updateSlidesClasses()},onDragStart:function(e){var t=this.params.scrollbar,i=this.scrollbar,s=this.$wrapperEl,a=i.$el,r=i.$dragEl;this.scrollbar.isTouched=!0,this.scrollbar.dragStartPos=e.target===r[0]||e.target===r?i.getPointerPosition(e)-e.target.getBoundingClientRect()[this.isHorizontal()?"left":"top"]:null,e.preventDefault(),e.stopPropagation(),s.transition(100),r.transition(100),i.setDragPosition(e),clearTimeout(this.scrollbar.dragTimeout),a.transition(0),t.hide&&a.css("opacity",1),this.params.cssMode&&this.$wrapperEl.css("scroll-snap-type","none"),this.emit("scrollbarDragStart",e)},onDragMove:function(e){var t=this.scrollbar,i=this.$wrapperEl,s=t.$el,a=t.$dragEl;this.scrollbar.isTouched&&(e.preventDefault?e.preventDefault():e.returnValue=!1,t.setDragPosition(e),i.transition(0),s.transition(0),a.transition(0),this.emit("scrollbarDragMove",e))},onDragEnd:function(e){var t=this.params.scrollbar,i=this.scrollbar,s=this.$wrapperEl,a=i.$el;this.scrollbar.isTouched&&(this.scrollbar.isTouched=!1,this.params.cssMode&&(this.$wrapperEl.css("scroll-snap-type",""),s.transition("")),t.hide&&(clearTimeout(this.scrollbar.dragTimeout),this.scrollbar.dragTimeout=n.nextTick((function(){a.css("opacity",0),a.transition(400)}),1e3)),this.emit("scrollbarDragEnd",e),t.snapOnRelease&&this.slideToClosest())},enableDraggable:function(){if(this.params.scrollbar.el){var t=this.scrollbar,i=this.touchEventsTouch,s=this.touchEventsDesktop,a=this.params,r=t.$el[0],n=!(!o.passiveListener||!a.passiveListeners)&&{passive:!1,capture:!1},l=!(!o.passiveListener||!a.passiveListeners)&&{passive:!0,capture:!1};o.touch?(r.addEventListener(i.start,this.scrollbar.onDragStart,n),r.addEventListener(i.move,this.scrollbar.onDragMove,n),r.addEventListener(i.end,this.scrollbar.onDragEnd,l)):(r.addEventListener(s.start,this.scrollbar.onDragStart,n),e.addEventListener(s.move,this.scrollbar.onDragMove,n),e.addEventListener(s.end,this.scrollbar.onDragEnd,l))}},disableDraggable:function(){if(this.params.scrollbar.el){var t=this.scrollbar,i=this.touchEventsTouch,s=this.touchEventsDesktop,a=this.params,r=t.$el[0],n=!(!o.passiveListener||!a.passiveListeners)&&{passive:!1,capture:!1},l=!(!o.passiveListener||!a.passiveListeners)&&{passive:!0,capture:!1};o.touch?(r.removeEventListener(i.start,this.scrollbar.onDragStart,n),r.removeEventListener(i.move,this.scrollbar.onDragMove,n),r.removeEventListener(i.end,this.scrollbar.onDragEnd,l)):(r.removeEventListener(s.start,this.scrollbar.onDragStart,n),e.removeEventListener(s.move,this.scrollbar.onDragMove,n),e.removeEventListener(s.end,this.scrollbar.onDragEnd,l))}},init:function(){if(this.params.scrollbar.el){var e=this.scrollbar,t=this.$el,i=this.params.scrollbar,a=s(i.el);this.params.uniqueNavElements&&"string"==typeof i.el&&a.length>1&&1===t.find(i.el).length&&(a=t.find(i.el));var r=a.find("."+this.params.scrollbar.dragClass);0===r.length&&(r=s('
'),a.append(r)),n.extend(e,{$el:a,el:a[0],$dragEl:r,dragEl:r[0]}),i.draggable&&e.enableDraggable()}},destroy:function(){this.scrollbar.disableDraggable()}},ne={setTransform:function(e,t){var i=this.rtl,a=s(e),r=i?-1:1,n=a.attr("data-swiper-parallax")||"0",o=a.attr("data-swiper-parallax-x"),l=a.attr("data-swiper-parallax-y"),d=a.attr("data-swiper-parallax-scale"),h=a.attr("data-swiper-parallax-opacity");if(o||l?(o=o||"0",l=l||"0"):this.isHorizontal()?(o=n,l="0"):(l=n,o="0"),o=o.indexOf("%")>=0?parseInt(o,10)*t*r+"%":o*t*r+"px",l=l.indexOf("%")>=0?parseInt(l,10)*t+"%":l*t+"px",null!=h){var p=h-(h-1)*(1-Math.abs(t));a[0].style.opacity=p}if(null==d)a.transform("translate3d("+o+", "+l+", 0px)");else{var c=d-(d-1)*(1-Math.abs(t));a.transform("translate3d("+o+", "+l+", 0px) scale("+c+")")}},setTranslate:function(){var e=this,t=e.$el,i=e.slides,a=e.progress,r=e.snapGrid;t.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t,i){e.parallax.setTransform(i,a)})),i.each((function(t,i){var n=i.progress;e.params.slidesPerGroup>1&&"auto"!==e.params.slidesPerView&&(n+=Math.ceil(t/2)-a*(r.length-1)),n=Math.min(Math.max(n,-1),1),s(i).find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t,i){e.parallax.setTransform(i,n)}))}))},setTransition:function(e){void 0===e&&(e=this.params.speed);this.$el.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t,i){var a=s(i),r=parseInt(a.attr("data-swiper-parallax-duration"),10)||e;0===e&&(r=0),a.transition(r)}))}},oe={getDistanceBetweenTouches:function(e){if(e.targetTouches.length<2)return 1;var t=e.targetTouches[0].pageX,i=e.targetTouches[0].pageY,s=e.targetTouches[1].pageX,a=e.targetTouches[1].pageY;return Math.sqrt(Math.pow(s-t,2)+Math.pow(a-i,2))},onGestureStart:function(e){var t=this.params.zoom,i=this.zoom,a=i.gesture;if(i.fakeGestureTouched=!1,i.fakeGestureMoved=!1,!o.gestures){if("touchstart"!==e.type||"touchstart"===e.type&&e.targetTouches.length<2)return;i.fakeGestureTouched=!0,a.scaleStart=oe.getDistanceBetweenTouches(e)}a.$slideEl&&a.$slideEl.length||(a.$slideEl=s(e.target).closest("."+this.params.slideClass),0===a.$slideEl.length&&(a.$slideEl=this.slides.eq(this.activeIndex)),a.$imageEl=a.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),a.$imageWrapEl=a.$imageEl.parent("."+t.containerClass),a.maxRatio=a.$imageWrapEl.attr("data-swiper-zoom")||t.maxRatio,0!==a.$imageWrapEl.length)?(a.$imageEl.transition(0),this.zoom.isScaling=!0):a.$imageEl=void 0},onGestureChange:function(e){var t=this.params.zoom,i=this.zoom,s=i.gesture;if(!o.gestures){if("touchmove"!==e.type||"touchmove"===e.type&&e.targetTouches.length<2)return;i.fakeGestureMoved=!0,s.scaleMove=oe.getDistanceBetweenTouches(e)}s.$imageEl&&0!==s.$imageEl.length&&(o.gestures?i.scale=e.scale*i.currentScale:i.scale=s.scaleMove/s.scaleStart*i.currentScale,i.scale>s.maxRatio&&(i.scale=s.maxRatio-1+Math.pow(i.scale-s.maxRatio+1,.5)),i.scales.touchesStart.x))return void(s.isTouched=!1);if(!this.isHorizontal()&&(Math.floor(s.minY)===Math.floor(s.startY)&&s.touchesCurrent.ys.touchesStart.y))return void(s.isTouched=!1)}e.preventDefault(),e.stopPropagation(),s.isMoved=!0,s.currentX=s.touchesCurrent.x-s.touchesStart.x+s.startX,s.currentY=s.touchesCurrent.y-s.touchesStart.y+s.startY,s.currentXs.maxX&&(s.currentX=s.maxX-1+Math.pow(s.currentX-s.maxX+1,.8)),s.currentYs.maxY&&(s.currentY=s.maxY-1+Math.pow(s.currentY-s.maxY+1,.8)),a.prevPositionX||(a.prevPositionX=s.touchesCurrent.x),a.prevPositionY||(a.prevPositionY=s.touchesCurrent.y),a.prevTime||(a.prevTime=Date.now()),a.x=(s.touchesCurrent.x-a.prevPositionX)/(Date.now()-a.prevTime)/2,a.y=(s.touchesCurrent.y-a.prevPositionY)/(Date.now()-a.prevTime)/2,Math.abs(s.touchesCurrent.x-a.prevPositionX)<2&&(a.x=0),Math.abs(s.touchesCurrent.y-a.prevPositionY)<2&&(a.y=0),a.prevPositionX=s.touchesCurrent.x,a.prevPositionY=s.touchesCurrent.y,a.prevTime=Date.now(),i.$imageWrapEl.transform("translate3d("+s.currentX+"px, "+s.currentY+"px,0)")}}},onTouchEnd:function(){var e=this.zoom,t=e.gesture,i=e.image,s=e.velocity;if(t.$imageEl&&0!==t.$imageEl.length){if(!i.isTouched||!i.isMoved)return i.isTouched=!1,void(i.isMoved=!1);i.isTouched=!1,i.isMoved=!1;var a=300,r=300,n=s.x*a,o=i.currentX+n,l=s.y*r,d=i.currentY+l;0!==s.x&&(a=Math.abs((o-i.currentX)/s.x)),0!==s.y&&(r=Math.abs((d-i.currentY)/s.y));var h=Math.max(a,r);i.currentX=o,i.currentY=d;var p=i.width*e.scale,c=i.height*e.scale;i.minX=Math.min(t.slideWidth/2-p/2,0),i.maxX=-i.minX,i.minY=Math.min(t.slideHeight/2-c/2,0),i.maxY=-i.minY,i.currentX=Math.max(Math.min(i.currentX,i.maxX),i.minX),i.currentY=Math.max(Math.min(i.currentY,i.maxY),i.minY),t.$imageWrapEl.transition(h).transform("translate3d("+i.currentX+"px, "+i.currentY+"px,0)")}},onTransitionEnd:function(){var e=this.zoom,t=e.gesture;t.$slideEl&&this.previousIndex!==this.activeIndex&&(t.$imageEl.transform("translate3d(0,0,0) scale(1)"),t.$imageWrapEl.transform("translate3d(0,0,0)"),e.scale=1,e.currentScale=1,t.$slideEl=void 0,t.$imageEl=void 0,t.$imageWrapEl=void 0)},toggle:function(e){var t=this.zoom;t.scale&&1!==t.scale?t.out():t.in(e)},in:function(e){var t,i,s,a,r,n,o,l,d,h,p,c,u,v,f,m,g=this.zoom,b=this.params.zoom,w=g.gesture,y=g.image;(w.$slideEl||(w.$slideEl=this.slides.eq(this.activeIndex),w.$imageEl=w.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),w.$imageWrapEl=w.$imageEl.parent("."+b.containerClass)),w.$imageEl&&0!==w.$imageEl.length)&&(w.$slideEl.addClass(""+b.zoomedSlideClass),void 0===y.touchesStart.x&&e?(t="touchend"===e.type?e.changedTouches[0].pageX:e.pageX,i="touchend"===e.type?e.changedTouches[0].pageY:e.pageY):(t=y.touchesStart.x,i=y.touchesStart.y),g.scale=w.$imageWrapEl.attr("data-swiper-zoom")||b.maxRatio,g.currentScale=w.$imageWrapEl.attr("data-swiper-zoom")||b.maxRatio,e?(f=w.$slideEl[0].offsetWidth,m=w.$slideEl[0].offsetHeight,s=w.$slideEl.offset().left+f/2-t,a=w.$slideEl.offset().top+m/2-i,o=w.$imageEl[0].offsetWidth,l=w.$imageEl[0].offsetHeight,d=o*g.scale,h=l*g.scale,u=-(p=Math.min(f/2-d/2,0)),v=-(c=Math.min(m/2-h/2,0)),(r=s*g.scale)u&&(r=u),(n=a*g.scale)v&&(n=v)):(r=0,n=0),w.$imageWrapEl.transition(300).transform("translate3d("+r+"px, "+n+"px,0)"),w.$imageEl.transition(300).transform("translate3d(0,0,0) scale("+g.scale+")"))},out:function(){var e=this.zoom,t=this.params.zoom,i=e.gesture;i.$slideEl||(i.$slideEl=this.slides.eq(this.activeIndex),i.$imageEl=i.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),i.$imageWrapEl=i.$imageEl.parent("."+t.containerClass)),i.$imageEl&&0!==i.$imageEl.length&&(e.scale=1,e.currentScale=1,i.$imageWrapEl.transition(300).transform("translate3d(0,0,0)"),i.$imageEl.transition(300).transform("translate3d(0,0,0) scale(1)"),i.$slideEl.removeClass(""+t.zoomedSlideClass),i.$slideEl=void 0)},enable:function(){var e=this.zoom;if(!e.enabled){e.enabled=!0;var t=!("touchstart"!==this.touchEvents.start||!o.passiveListener||!this.params.passiveListeners)&&{passive:!0,capture:!1},i=!o.passiveListener||{passive:!1,capture:!0},s="."+this.params.slideClass;o.gestures?(this.$wrapperEl.on("gesturestart",s,e.onGestureStart,t),this.$wrapperEl.on("gesturechange",s,e.onGestureChange,t),this.$wrapperEl.on("gestureend",s,e.onGestureEnd,t)):"touchstart"===this.touchEvents.start&&(this.$wrapperEl.on(this.touchEvents.start,s,e.onGestureStart,t),this.$wrapperEl.on(this.touchEvents.move,s,e.onGestureChange,i),this.$wrapperEl.on(this.touchEvents.end,s,e.onGestureEnd,t),this.touchEvents.cancel&&this.$wrapperEl.on(this.touchEvents.cancel,s,e.onGestureEnd,t)),this.$wrapperEl.on(this.touchEvents.move,"."+this.params.zoom.containerClass,e.onTouchMove,i)}},disable:function(){var e=this.zoom;if(e.enabled){this.zoom.enabled=!1;var t=!("touchstart"!==this.touchEvents.start||!o.passiveListener||!this.params.passiveListeners)&&{passive:!0,capture:!1},i=!o.passiveListener||{passive:!1,capture:!0},s="."+this.params.slideClass;o.gestures?(this.$wrapperEl.off("gesturestart",s,e.onGestureStart,t),this.$wrapperEl.off("gesturechange",s,e.onGestureChange,t),this.$wrapperEl.off("gestureend",s,e.onGestureEnd,t)):"touchstart"===this.touchEvents.start&&(this.$wrapperEl.off(this.touchEvents.start,s,e.onGestureStart,t),this.$wrapperEl.off(this.touchEvents.move,s,e.onGestureChange,i),this.$wrapperEl.off(this.touchEvents.end,s,e.onGestureEnd,t),this.touchEvents.cancel&&this.$wrapperEl.off(this.touchEvents.cancel,s,e.onGestureEnd,t)),this.$wrapperEl.off(this.touchEvents.move,"."+this.params.zoom.containerClass,e.onTouchMove,i)}}},le={loadInSlide:function(e,t){void 0===t&&(t=!0);var i=this,a=i.params.lazy;if(void 0!==e&&0!==i.slides.length){var r=i.virtual&&i.params.virtual.enabled?i.$wrapperEl.children("."+i.params.slideClass+'[data-swiper-slide-index="'+e+'"]'):i.slides.eq(e),n=r.find("."+a.elementClass+":not(."+a.loadedClass+"):not(."+a.loadingClass+")");!r.hasClass(a.elementClass)||r.hasClass(a.loadedClass)||r.hasClass(a.loadingClass)||(n=n.add(r[0])),0!==n.length&&n.each((function(e,n){var o=s(n);o.addClass(a.loadingClass);var l=o.attr("data-background"),d=o.attr("data-src"),h=o.attr("data-srcset"),p=o.attr("data-sizes");i.loadImage(o[0],d||l,h,p,!1,(function(){if(null!=i&&i&&(!i||i.params)&&!i.destroyed){if(l?(o.css("background-image",'url("'+l+'")'),o.removeAttr("data-background")):(h&&(o.attr("srcset",h),o.removeAttr("data-srcset")),p&&(o.attr("sizes",p),o.removeAttr("data-sizes")),d&&(o.attr("src",d),o.removeAttr("data-src"))),o.addClass(a.loadedClass).removeClass(a.loadingClass),r.find("."+a.preloaderClass).remove(),i.params.loop&&t){var e=r.attr("data-swiper-slide-index");if(r.hasClass(i.params.slideDuplicateClass)){var s=i.$wrapperEl.children('[data-swiper-slide-index="'+e+'"]:not(.'+i.params.slideDuplicateClass+")");i.lazy.loadInSlide(s.index(),!1)}else{var n=i.$wrapperEl.children("."+i.params.slideDuplicateClass+'[data-swiper-slide-index="'+e+'"]');i.lazy.loadInSlide(n.index(),!1)}}i.emit("lazyImageReady",r[0],o[0]),i.params.autoHeight&&i.updateAutoHeight()}})),i.emit("lazyImageLoad",r[0],o[0])}))}},load:function(){var e=this,t=e.$wrapperEl,i=e.params,a=e.slides,r=e.activeIndex,n=e.virtual&&i.virtual.enabled,o=i.lazy,l=i.slidesPerView;function d(e){if(n){if(t.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]').length)return!0}else if(a[e])return!0;return!1}function h(e){return n?s(e).attr("data-swiper-slide-index"):s(e).index()}if("auto"===l&&(l=0),e.lazy.initialImageLoaded||(e.lazy.initialImageLoaded=!0),e.params.watchSlidesVisibility)t.children("."+i.slideVisibleClass).each((function(t,i){var a=n?s(i).attr("data-swiper-slide-index"):s(i).index();e.lazy.loadInSlide(a)}));else if(l>1)for(var p=r;p1||o.loadPrevNextAmount&&o.loadPrevNextAmount>1){for(var c=o.loadPrevNextAmount,u=l,v=Math.min(r+u+Math.max(c,u),a.length),f=Math.max(r-Math.max(u,c),0),m=r+l;m0&&e.lazy.loadInSlide(h(b));var w=t.children("."+i.slidePrevClass);w.length>0&&e.lazy.loadInSlide(h(w))}}},de={LinearSpline:function(e,t){var i,s,a,r,n,o=function(e,t){for(s=-1,i=e.length;i-s>1;)e[a=i+s>>1]<=t?s=a:i=a;return i};return this.x=e,this.y=t,this.lastIndex=e.length-1,this.interpolate=function(e){return e?(n=o(this.x,e),r=n-1,(e-this.x[r])*(this.y[n]-this.y[r])/(this.x[n]-this.x[r])+this.y[r]):0},this},getInterpolateFunction:function(e){this.controller.spline||(this.controller.spline=this.params.loop?new de.LinearSpline(this.slidesGrid,e.slidesGrid):new de.LinearSpline(this.snapGrid,e.snapGrid))},setTranslate:function(e,t){var i,s,a=this,r=a.controller.control;function n(e){var t=a.rtlTranslate?-a.translate:a.translate;"slide"===a.params.controller.by&&(a.controller.getInterpolateFunction(e),s=-a.controller.spline.interpolate(-t)),s&&"container"!==a.params.controller.by||(i=(e.maxTranslate()-e.minTranslate())/(a.maxTranslate()-a.minTranslate()),s=(t-a.minTranslate())*i+e.minTranslate()),a.params.controller.inverse&&(s=e.maxTranslate()-s),e.updateProgress(s),e.setTranslate(s,a),e.updateActiveIndex(),e.updateSlidesClasses()}if(Array.isArray(r))for(var o=0;o0&&(this.isBeginning?this.a11y.disableEl(i):this.a11y.enableEl(i)),t&&t.length>0&&(this.isEnd?this.a11y.disableEl(t):this.a11y.enableEl(t))}},updatePagination:function(){var e=this,t=e.params.a11y;e.pagination&&e.params.pagination.clickable&&e.pagination.bullets&&e.pagination.bullets.length&&e.pagination.bullets.each((function(i,a){var r=s(a);e.a11y.makeElFocusable(r),e.a11y.addElRole(r,"button"),e.a11y.addElLabel(r,t.paginationBulletMessage.replace(/{{index}}/,r.index()+1))}))},init:function(){this.$el.append(this.a11y.liveRegion);var e,t,i=this.params.a11y;this.navigation&&this.navigation.$nextEl&&(e=this.navigation.$nextEl),this.navigation&&this.navigation.$prevEl&&(t=this.navigation.$prevEl),e&&(this.a11y.makeElFocusable(e),this.a11y.addElRole(e,"button"),this.a11y.addElLabel(e,i.nextSlideMessage),e.on("keydown",this.a11y.onEnterKey)),t&&(this.a11y.makeElFocusable(t),this.a11y.addElRole(t,"button"),this.a11y.addElLabel(t,i.prevSlideMessage),t.on("keydown",this.a11y.onEnterKey)),this.pagination&&this.params.pagination.clickable&&this.pagination.bullets&&this.pagination.bullets.length&&this.pagination.$el.on("keydown","."+this.params.pagination.bulletClass,this.a11y.onEnterKey)},destroy:function(){var e,t;this.a11y.liveRegion&&this.a11y.liveRegion.length>0&&this.a11y.liveRegion.remove(),this.navigation&&this.navigation.$nextEl&&(e=this.navigation.$nextEl),this.navigation&&this.navigation.$prevEl&&(t=this.navigation.$prevEl),e&&e.off("keydown",this.a11y.onEnterKey),t&&t.off("keydown",this.a11y.onEnterKey),this.pagination&&this.params.pagination.clickable&&this.pagination.bullets&&this.pagination.bullets.length&&this.pagination.$el.off("keydown","."+this.params.pagination.bulletClass,this.a11y.onEnterKey)}},pe={init:function(){if(this.params.history){if(!t.history||!t.history.pushState)return this.params.history.enabled=!1,void(this.params.hashNavigation.enabled=!0);var e=this.history;e.initialized=!0,e.paths=pe.getPathValues(),(e.paths.key||e.paths.value)&&(e.scrollToSlide(0,e.paths.value,this.params.runCallbacksOnInit),this.params.history.replaceState||t.addEventListener("popstate",this.history.setHistoryPopState))}},destroy:function(){this.params.history.replaceState||t.removeEventListener("popstate",this.history.setHistoryPopState)},setHistoryPopState:function(){this.history.paths=pe.getPathValues(),this.history.scrollToSlide(this.params.speed,this.history.paths.value,!1)},getPathValues:function(){var e=t.location.pathname.slice(1).split("/").filter((function(e){return""!==e})),i=e.length;return{key:e[i-2],value:e[i-1]}},setHistory:function(e,i){if(this.history.initialized&&this.params.history.enabled){var s=this.slides.eq(i),a=pe.slugify(s.attr("data-history"));t.location.pathname.includes(e)||(a=e+"/"+a);var r=t.history.state;r&&r.value===a||(this.params.history.replaceState?t.history.replaceState({value:a},null,a):t.history.pushState({value:a},null,a))}},slugify:function(e){return e.toString().replace(/\s+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+/,"").replace(/-+$/,"")},scrollToSlide:function(e,t,i){if(t)for(var s=0,a=this.slides.length;s'),i.append(e)),e.css({height:r+"px"})):0===(e=t.find(".swiper-cube-shadow")).length&&(e=s('
'),t.append(e)));for(var u=0;u-1&&(c=90*f+90*b,o&&(c=90*-f-90*b)),v.transform(T),d.slideShadows){var E=h?v.find(".swiper-slide-shadow-left"):v.find(".swiper-slide-shadow-top"),S=h?v.find(".swiper-slide-shadow-right"):v.find(".swiper-slide-shadow-bottom");0===E.length&&(E=s('
'),v.append(E)),0===S.length&&(S=s('
'),v.append(S)),E.length&&(E[0].style.opacity=Math.max(-b,0)),S.length&&(S[0].style.opacity=Math.max(b,0))}}if(i.css({"-webkit-transform-origin":"50% 50% -"+l/2+"px","-moz-transform-origin":"50% 50% -"+l/2+"px","-ms-transform-origin":"50% 50% -"+l/2+"px","transform-origin":"50% 50% -"+l/2+"px"}),d.shadow)if(h)e.transform("translate3d(0px, "+(r/2+d.shadowOffset)+"px, "+-r/2+"px) rotateX(90deg) rotateZ(0deg) scale("+d.shadowScale+")");else{var C=Math.abs(c)-90*Math.floor(Math.abs(c)/90),M=1.5-(Math.sin(2*C*Math.PI/360)/2+Math.cos(2*C*Math.PI/360)/2),P=d.shadowScale,z=d.shadowScale/M,k=d.shadowOffset;e.transform("scale3d("+P+", 1, "+z+") translate3d(0px, "+(n/2+k)+"px, "+-n/2/z+"px) rotateX(-90deg)")}var $=j.isSafari||j.isUiWebView?-l/2:0;i.transform("translate3d(0px,0,"+$+"px) rotateX("+(this.isHorizontal()?0:c)+"deg) rotateY("+(this.isHorizontal()?-c:0)+"deg)")},setTransition:function(e){var t=this.$el;this.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),this.params.cubeEffect.shadow&&!this.isHorizontal()&&t.find(".swiper-cube-shadow").transition(e)}},me={setTranslate:function(){for(var e=this.slides,t=this.rtlTranslate,i=0;i'),a.append(h)),0===p.length&&(p=s('
'),a.append(p)),h.length&&(h[0].style.opacity=Math.max(-r,0)),p.length&&(p[0].style.opacity=Math.max(r,0))}a.transform("translate3d("+l+"px, "+d+"px, 0px) rotateX("+o+"deg) rotateY("+n+"deg)")}},setTransition:function(e){var t=this,i=t.slides,s=t.activeIndex,a=t.$wrapperEl;if(i.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),t.params.virtualTranslate&&0!==e){var r=!1;i.eq(s).transitionEnd((function(){if(!r&&t&&!t.destroyed){r=!0,t.animating=!1;for(var e=["webkitTransitionEnd","transitionend"],i=0;i'),f.append(C)),0===M.length&&(M=s('
'),f.append(M)),C.length&&(C[0].style.opacity=g>0?g:0),M.length&&(M[0].style.opacity=-g>0?-g:0)}}(o.pointerEvents||o.prefixedPointerEvents)&&(a[0].style.perspectiveOrigin=h+"px 50%")},setTransition:function(e){this.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}},be={init:function(){var e=this.params.thumbs,t=this.constructor;e.swiper instanceof t?(this.thumbs.swiper=e.swiper,n.extend(this.thumbs.swiper.originalParams,{watchSlidesProgress:!0,slideToClickedSlide:!1}),n.extend(this.thumbs.swiper.params,{watchSlidesProgress:!0,slideToClickedSlide:!1})):n.isObject(e.swiper)&&(this.thumbs.swiper=new t(n.extend({},e.swiper,{watchSlidesVisibility:!0,watchSlidesProgress:!0,slideToClickedSlide:!1})),this.thumbs.swiperCreated=!0),this.thumbs.swiper.$el.addClass(this.params.thumbs.thumbsContainerClass),this.thumbs.swiper.on("tap",this.thumbs.onThumbClick)},onThumbClick:function(){var e=this.thumbs.swiper;if(e){var t=e.clickedIndex,i=e.clickedSlide;if(!(i&&s(i).hasClass(this.params.thumbs.slideThumbActiveClass)||null==t)){var a;if(a=e.params.loop?parseInt(s(e.clickedSlide).attr("data-swiper-slide-index"),10):t,this.params.loop){var r=this.activeIndex;this.slides.eq(r).hasClass(this.params.slideDuplicateClass)&&(this.loopFix(),this._clientLeft=this.$wrapperEl[0].clientLeft,r=this.activeIndex);var n=this.slides.eq(r).prevAll('[data-swiper-slide-index="'+a+'"]').eq(0).index(),o=this.slides.eq(r).nextAll('[data-swiper-slide-index="'+a+'"]').eq(0).index();a=void 0===n?o:void 0===o?n:o-ra?s-Math.floor(i/2)+1:s+Math.floor(i/2)-1:s>a&&(s=s-i+1),t.slideTo(s,e?0:void 0))}var o=1,l=this.params.thumbs.slideThumbActiveClass;if(this.params.slidesPerView>1&&!this.params.centeredSlides&&(o=this.params.slidesPerView),this.params.thumbs.multipleActiveThumbs||(o=1),o=Math.floor(o),t.slides.removeClass(l),t.params.loop||t.params.virtual&&t.params.virtual.enabled)for(var d=0;d0&&!s(e.target).hasClass(this.params.pagination.bulletClass)&&(!0===this.pagination.$el.hasClass(this.params.pagination.hiddenClass)?this.emit("paginationShow",this):this.emit("paginationHide",this),this.pagination.$el.toggleClass(this.params.pagination.hiddenClass))}}},{name:"scrollbar",params:{scrollbar:{el:null,dragSize:"auto",hide:!1,draggable:!1,snapOnRelease:!0,lockClass:"swiper-scrollbar-lock",dragClass:"swiper-scrollbar-drag"}},create:function(){n.extend(this,{scrollbar:{init:re.init.bind(this),destroy:re.destroy.bind(this),updateSize:re.updateSize.bind(this),setTranslate:re.setTranslate.bind(this),setTransition:re.setTransition.bind(this),enableDraggable:re.enableDraggable.bind(this),disableDraggable:re.disableDraggable.bind(this),setDragPosition:re.setDragPosition.bind(this),getPointerPosition:re.getPointerPosition.bind(this),onDragStart:re.onDragStart.bind(this),onDragMove:re.onDragMove.bind(this),onDragEnd:re.onDragEnd.bind(this),isTouched:!1,timeout:null,dragTimeout:null}})},on:{init:function(){this.scrollbar.init(),this.scrollbar.updateSize(),this.scrollbar.setTranslate()},update:function(){this.scrollbar.updateSize()},resize:function(){this.scrollbar.updateSize()},observerUpdate:function(){this.scrollbar.updateSize()},setTranslate:function(){this.scrollbar.setTranslate()},setTransition:function(e){this.scrollbar.setTransition(e)},destroy:function(){this.scrollbar.destroy()}}},{name:"parallax",params:{parallax:{enabled:!1}},create:function(){n.extend(this,{parallax:{setTransform:ne.setTransform.bind(this),setTranslate:ne.setTranslate.bind(this),setTransition:ne.setTransition.bind(this)}})},on:{beforeInit:function(){this.params.parallax.enabled&&(this.params.watchSlidesProgress=!0,this.originalParams.watchSlidesProgress=!0)},init:function(){this.params.parallax.enabled&&this.parallax.setTranslate()},setTranslate:function(){this.params.parallax.enabled&&this.parallax.setTranslate()},setTransition:function(e){this.params.parallax.enabled&&this.parallax.setTransition(e)}}},{name:"zoom",params:{zoom:{enabled:!1,maxRatio:3,minRatio:1,toggle:!0,containerClass:"swiper-zoom-container",zoomedSlideClass:"swiper-slide-zoomed"}},create:function(){var e=this,t={enabled:!1,scale:1,currentScale:1,isScaling:!1,gesture:{$slideEl:void 0,slideWidth:void 0,slideHeight:void 0,$imageEl:void 0,$imageWrapEl:void 0,maxRatio:3},image:{isTouched:void 0,isMoved:void 0,currentX:void 0,currentY:void 0,minX:void 0,minY:void 0,maxX:void 0,maxY:void 0,width:void 0,height:void 0,startX:void 0,startY:void 0,touchesStart:{},touchesCurrent:{}},velocity:{x:void 0,y:void 0,prevPositionX:void 0,prevPositionY:void 0,prevTime:void 0}};"onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out".split(" ").forEach((function(i){t[i]=oe[i].bind(e)})),n.extend(e,{zoom:t});var i=1;Object.defineProperty(e.zoom,"scale",{get:function(){return i},set:function(t){if(i!==t){var s=e.zoom.gesture.$imageEl?e.zoom.gesture.$imageEl[0]:void 0,a=e.zoom.gesture.$slideEl?e.zoom.gesture.$slideEl[0]:void 0;e.emit("zoomChange",t,s,a)}i=t}})},on:{init:function(){this.params.zoom.enabled&&this.zoom.enable()},destroy:function(){this.zoom.disable()},touchStart:function(e){this.zoom.enabled&&this.zoom.onTouchStart(e)},touchEnd:function(e){this.zoom.enabled&&this.zoom.onTouchEnd(e)},doubleTap:function(e){this.params.zoom.enabled&&this.zoom.enabled&&this.params.zoom.toggle&&this.zoom.toggle(e)},transitionEnd:function(){this.zoom.enabled&&this.params.zoom.enabled&&this.zoom.onTransitionEnd()},slideChange:function(){this.zoom.enabled&&this.params.zoom.enabled&&this.params.cssMode&&this.zoom.onTransitionEnd()}}},{name:"lazy",params:{lazy:{enabled:!1,loadPrevNext:!1,loadPrevNextAmount:1,loadOnTransitionStart:!1,elementClass:"swiper-lazy",loadingClass:"swiper-lazy-loading",loadedClass:"swiper-lazy-loaded",preloaderClass:"swiper-lazy-preloader"}},create:function(){n.extend(this,{lazy:{initialImageLoaded:!1,load:le.load.bind(this),loadInSlide:le.loadInSlide.bind(this)}})},on:{beforeInit:function(){this.params.lazy.enabled&&this.params.preloadImages&&(this.params.preloadImages=!1)},init:function(){this.params.lazy.enabled&&!this.params.loop&&0===this.params.initialSlide&&this.lazy.load()},scroll:function(){this.params.freeMode&&!this.params.freeModeSticky&&this.lazy.load()},resize:function(){this.params.lazy.enabled&&this.lazy.load()},scrollbarDragMove:function(){this.params.lazy.enabled&&this.lazy.load()},transitionStart:function(){this.params.lazy.enabled&&(this.params.lazy.loadOnTransitionStart||!this.params.lazy.loadOnTransitionStart&&!this.lazy.initialImageLoaded)&&this.lazy.load()},transitionEnd:function(){this.params.lazy.enabled&&!this.params.lazy.loadOnTransitionStart&&this.lazy.load()},slideChange:function(){this.params.lazy.enabled&&this.params.cssMode&&this.lazy.load()}}},{name:"controller",params:{controller:{control:void 0,inverse:!1,by:"slide"}},create:function(){n.extend(this,{controller:{control:this.params.controller.control,getInterpolateFunction:de.getInterpolateFunction.bind(this),setTranslate:de.setTranslate.bind(this),setTransition:de.setTransition.bind(this)}})},on:{update:function(){this.controller.control&&this.controller.spline&&(this.controller.spline=void 0,delete this.controller.spline)},resize:function(){this.controller.control&&this.controller.spline&&(this.controller.spline=void 0,delete this.controller.spline)},observerUpdate:function(){this.controller.control&&this.controller.spline&&(this.controller.spline=void 0,delete this.controller.spline)},setTranslate:function(e,t){this.controller.control&&this.controller.setTranslate(e,t)},setTransition:function(e,t){this.controller.control&&this.controller.setTransition(e,t)}}},{name:"a11y",params:{a11y:{enabled:!0,notificationClass:"swiper-notification",prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}"}},create:function(){var e=this;n.extend(e,{a11y:{liveRegion:s('')}}),Object.keys(he).forEach((function(t){e.a11y[t]=he[t].bind(e)}))},on:{init:function(){this.params.a11y.enabled&&(this.a11y.init(),this.a11y.updateNavigation())},toEdge:function(){this.params.a11y.enabled&&this.a11y.updateNavigation()},fromEdge:function(){this.params.a11y.enabled&&this.a11y.updateNavigation()},paginationUpdate:function(){this.params.a11y.enabled&&this.a11y.updatePagination()},destroy:function(){this.params.a11y.enabled&&this.a11y.destroy()}}},{name:"history",params:{history:{enabled:!1,replaceState:!1,key:"slides"}},create:function(){n.extend(this,{history:{init:pe.init.bind(this),setHistory:pe.setHistory.bind(this),setHistoryPopState:pe.setHistoryPopState.bind(this),scrollToSlide:pe.scrollToSlide.bind(this),destroy:pe.destroy.bind(this)}})},on:{init:function(){this.params.history.enabled&&this.history.init()},destroy:function(){this.params.history.enabled&&this.history.destroy()},transitionEnd:function(){this.history.initialized&&this.history.setHistory(this.params.history.key,this.activeIndex)},slideChange:function(){this.history.initialized&&this.params.cssMode&&this.history.setHistory(this.params.history.key,this.activeIndex)}}},{name:"hash-navigation",params:{hashNavigation:{enabled:!1,replaceState:!1,watchState:!1}},create:function(){n.extend(this,{hashNavigation:{initialized:!1,init:ce.init.bind(this),destroy:ce.destroy.bind(this),setHash:ce.setHash.bind(this),onHashCange:ce.onHashCange.bind(this)}})},on:{init:function(){this.params.hashNavigation.enabled&&this.hashNavigation.init()},destroy:function(){this.params.hashNavigation.enabled&&this.hashNavigation.destroy()},transitionEnd:function(){this.hashNavigation.initialized&&this.hashNavigation.setHash()},slideChange:function(){this.hashNavigation.initialized&&this.params.cssMode&&this.hashNavigation.setHash()}}},{name:"autoplay",params:{autoplay:{enabled:!1,delay:3e3,waitForTransition:!0,disableOnInteraction:!0,stopOnLastSlide:!1,reverseDirection:!1}},create:function(){var e=this;n.extend(e,{autoplay:{running:!1,paused:!1,run:ue.run.bind(e),start:ue.start.bind(e),stop:ue.stop.bind(e),pause:ue.pause.bind(e),onVisibilityChange:function(){"hidden"===document.visibilityState&&e.autoplay.running&&e.autoplay.pause(),"visible"===document.visibilityState&&e.autoplay.paused&&(e.autoplay.run(),e.autoplay.paused=!1)},onTransitionEnd:function(t){e&&!e.destroyed&&e.$wrapperEl&&t.target===this&&(e.$wrapperEl[0].removeEventListener("transitionend",e.autoplay.onTransitionEnd),e.$wrapperEl[0].removeEventListener("webkitTransitionEnd",e.autoplay.onTransitionEnd),e.autoplay.paused=!1,e.autoplay.running?e.autoplay.run():e.autoplay.stop())}}})},on:{init:function(){this.params.autoplay.enabled&&(this.autoplay.start(),document.addEventListener("visibilitychange",this.autoplay.onVisibilityChange))},beforeTransitionStart:function(e,t){this.autoplay.running&&(t||!this.params.autoplay.disableOnInteraction?this.autoplay.pause(e):this.autoplay.stop())},sliderFirstMove:function(){this.autoplay.running&&(this.params.autoplay.disableOnInteraction?this.autoplay.stop():this.autoplay.pause())},touchEnd:function(){this.params.cssMode&&this.autoplay.paused&&!this.params.autoplay.disableOnInteraction&&this.autoplay.run()},destroy:function(){this.autoplay.running&&this.autoplay.stop(),document.removeEventListener("visibilitychange",this.autoplay.onVisibilityChange)}}},{name:"effect-fade",params:{fadeEffect:{crossFade:!1}},create:function(){n.extend(this,{fadeEffect:{setTranslate:ve.setTranslate.bind(this),setTransition:ve.setTransition.bind(this)}})},on:{beforeInit:function(){if("fade"===this.params.effect){this.classNames.push(this.params.containerModifierClass+"fade");var e={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};n.extend(this.params,e),n.extend(this.originalParams,e)}},setTranslate:function(){"fade"===this.params.effect&&this.fadeEffect.setTranslate()},setTransition:function(e){"fade"===this.params.effect&&this.fadeEffect.setTransition(e)}}},{name:"effect-cube",params:{cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94}},create:function(){n.extend(this,{cubeEffect:{setTranslate:fe.setTranslate.bind(this),setTransition:fe.setTransition.bind(this)}})},on:{beforeInit:function(){if("cube"===this.params.effect){this.classNames.push(this.params.containerModifierClass+"cube"),this.classNames.push(this.params.containerModifierClass+"3d");var e={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,resistanceRatio:0,spaceBetween:0,centeredSlides:!1,virtualTranslate:!0};n.extend(this.params,e),n.extend(this.originalParams,e)}},setTranslate:function(){"cube"===this.params.effect&&this.cubeEffect.setTranslate()},setTransition:function(e){"cube"===this.params.effect&&this.cubeEffect.setTransition(e)}}},{name:"effect-flip",params:{flipEffect:{slideShadows:!0,limitRotation:!0}},create:function(){n.extend(this,{flipEffect:{setTranslate:me.setTranslate.bind(this),setTransition:me.setTransition.bind(this)}})},on:{beforeInit:function(){if("flip"===this.params.effect){this.classNames.push(this.params.containerModifierClass+"flip"),this.classNames.push(this.params.containerModifierClass+"3d");var e={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};n.extend(this.params,e),n.extend(this.originalParams,e)}},setTranslate:function(){"flip"===this.params.effect&&this.flipEffect.setTranslate()},setTransition:function(e){"flip"===this.params.effect&&this.flipEffect.setTransition(e)}}},{name:"effect-coverflow",params:{coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0}},create:function(){n.extend(this,{coverflowEffect:{setTranslate:ge.setTranslate.bind(this),setTransition:ge.setTransition.bind(this)}})},on:{beforeInit:function(){"coverflow"===this.params.effect&&(this.classNames.push(this.params.containerModifierClass+"coverflow"),this.classNames.push(this.params.containerModifierClass+"3d"),this.params.watchSlidesProgress=!0,this.originalParams.watchSlidesProgress=!0)},setTranslate:function(){"coverflow"===this.params.effect&&this.coverflowEffect.setTranslate()},setTransition:function(e){"coverflow"===this.params.effect&&this.coverflowEffect.setTransition(e)}}},{name:"thumbs",params:{thumbs:{multipleActiveThumbs:!0,swiper:null,slideThumbActiveClass:"swiper-slide-thumb-active",thumbsContainerClass:"swiper-container-thumbs"}},create:function(){n.extend(this,{thumbs:{swiper:null,init:be.init.bind(this),update:be.update.bind(this),onThumbClick:be.onThumbClick.bind(this)}})},on:{beforeInit:function(){var e=this.params.thumbs;e&&e.swiper&&(this.thumbs.init(),this.thumbs.update(!0))},slideChange:function(){this.thumbs.swiper&&this.thumbs.update()},update:function(){this.thumbs.swiper&&this.thumbs.update()},resize:function(){this.thumbs.swiper&&this.thumbs.update()},observerUpdate:function(){this.thumbs.swiper&&this.thumbs.update()},setTransition:function(e){var t=this.thumbs.swiper;t&&t.setTransition(e)},beforeDestroy:function(){var e=this.thumbs.swiper;e&&this.thumbs.swiperCreated&&e&&e.destroy()}}}];return void 0===W.use&&(W.use=W.Class.use,W.installModule=W.Class.installModule),W.use(we),W})); +//# sourceMappingURL=swiper.min.js.map \ No newline at end of file diff --git a/public/js/vendor.js b/public/js/vendor.js new file mode 100644 index 0000000..8e1ac24 --- /dev/null +++ b/public/js/vendor.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[898],{306:(e,t,n)=>{n.d(t,{Z:()=>Cn});var r,i,o,a,s=!1,l=!1,c=[];function u(e){!function(e){c.includes(e)||c.push(e);l||s||(s=!0,queueMicrotask(d))}(e)}function f(e){let t=c.indexOf(e);-1!==t&&c.splice(t,1)}function d(){s=!1,l=!0;for(let e=0;e{(void 0===t||t.includes(n))&&(r.forEach((e=>e())),delete e._x_attributeCleanups[n])}))}var y=new MutationObserver($),b=!1;function w(){y.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),b=!0}function E(){(k=k.concat(y.takeRecords())).length&&!A&&(A=!0,queueMicrotask((()=>{$(k),k.length=0,A=!1}))),y.disconnect(),b=!1}var k=[],A=!1;function O(e){if(!b)return e();E();let t=e();return w(),t}var S=!1,C=[];function $(e){if(S)return void(C=C.concat(e));let t=[],n=[],r=new Map,i=new Map;for(let o=0;o1===e.nodeType&&t.push(e))),e[o].removedNodes.forEach((e=>1===e.nodeType&&n.push(e)))),"attributes"===e[o].type)){let t=e[o].target,n=e[o].attributeName,a=e[o].oldValue,s=()=>{r.has(t)||r.set(t,[]),r.get(t).push({name:n,value:t.getAttribute(n)})},l=()=>{i.has(t)||i.set(t,[]),i.get(t).push(n)};t.hasAttribute(n)&&null===a?s():t.hasAttribute(n)?(l(),s()):l()}i.forEach(((e,t)=>{v(t,e)})),r.forEach(((e,t)=>{h.forEach((n=>n(t,e)))}));for(let e of n)if(!t.includes(e)&&(m.forEach((t=>t(e))),e._x_cleanups))for(;e._x_cleanups.length;)e._x_cleanups.pop()();t.forEach((e=>{e._x_ignoreSelf=!0,e._x_ignore=!0}));for(let e of t)n.includes(e)||e.isConnected&&(delete e._x_ignoreSelf,delete e._x_ignore,x.forEach((t=>t(e))),e._x_ignore=!0,e._x_ignoreSelf=!0);t.forEach((e=>{delete e._x_ignoreSelf,delete e._x_ignore})),t=null,n=null,r=null,i=null}function j(e){return P(N(e))}function M(e,t,n){return e._x_dataStack=[t,...N(n||e)],()=>{e._x_dataStack=e._x_dataStack.filter((e=>e!==t))}}function L(e,t){let n=e._x_dataStack[0];Object.entries(t).forEach((([e,t])=>{n[e]=t}))}function N(e){return e._x_dataStack?e._x_dataStack:"function"==typeof ShadowRoot&&e instanceof ShadowRoot?N(e.host):e.parentNode?N(e.parentNode):[]}function P(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap((e=>Object.keys(e))))),has:(t,n)=>e.some((e=>e.hasOwnProperty(n))),get:(n,r)=>(e.find((e=>{if(e.hasOwnProperty(r)){let n=Object.getOwnPropertyDescriptor(e,r);if(n.get&&n.get._x_alreadyBound||n.set&&n.set._x_alreadyBound)return!0;if((n.get||n.set)&&n.enumerable){let i=n.get,o=n.set,a=n;i=i&&i.bind(t),o=o&&o.bind(t),i&&(i._x_alreadyBound=!0),o&&(o._x_alreadyBound=!0),Object.defineProperty(e,r,{...a,get:i,set:o})}return!0}return!1}))||{})[r],set:(t,n,r)=>{let i=e.find((e=>e.hasOwnProperty(n)));return i?i[n]=r:e[e.length-1][n]=r,!0}});return t}function R(e){let t=(n,r="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach((([i,{value:o,enumerable:a}])=>{if(!1===a||void 0===o)return;let s=""===r?i:`${r}.${i}`;var l;"object"==typeof o&&null!==o&&o._x_interceptor?n[i]=o.initialize(e,s,i):"object"!=typeof(l=o)||Array.isArray(l)||null===l||o===n||o instanceof Element||t(o,s)}))};return t(e)}function T(e,t=(()=>{})){let n={initialValue:void 0,_x_interceptor:!0,initialize(t,n,r){return e(this.initialValue,(()=>function(e,t){return t.split(".").reduce(((e,t)=>e[t]),e)}(t,n)),(e=>z(t,n,e)),n,r)}};return t(n),e=>{if("object"==typeof e&&null!==e&&e._x_interceptor){let t=n.initialize.bind(n);n.initialize=(r,i,o)=>{let a=e.initialize(r,i,o);return n.initialValue=a,t(r,i,o)}}else n.initialValue=e;return n}}function z(e,t,n){if("string"==typeof t&&(t=t.split(".")),1!==t.length){if(0===t.length)throw error;return e[t[0]]||(e[t[0]]={}),z(e[t[0]],t.slice(1),n)}e[t[0]]=n}var I={};function D(e,t){I[e]=t}function q(e,t){return Object.entries(I).forEach((([n,r])=>{Object.defineProperty(e,`$${n}`,{get(){let[e,n]=oe(t);return e={interceptor:T,...e},g(t,n),r(t,e)},enumerable:!1})})),e}function W(e,t,n,...r){try{return n(...r)}catch(n){B(n,e,t)}}function B(e,t,n){Object.assign(e,{el:t,expression:n}),console.warn(`Alpine Expression Error: ${e.message}\n\n${n?'Expression: "'+n+'"\n\n':""}`,t),setTimeout((()=>{throw e}),0)}var F=!0;function V(e,t,n={}){let r;return K(e,t)((e=>r=e),n),r}function K(...e){return U(...e)}var U=H;function H(e,t){let n={};q(n,e);let r=[n,...N(e)];if("function"==typeof t)return function(e,t){return(n=(()=>{}),{scope:r={},params:i=[]}={})=>{Y(n,t.apply(P([r,...e]),i))}}(r,t);let i=function(e,t,n){let r=function(e,t){if(Z[e])return Z[e];let n=Object.getPrototypeOf((async function(){})).constructor,r=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;let i=(()=>{try{return new n(["__self","scope"],`with (scope) { __self.result = ${r} }; __self.finished = true; return __self.result;`)}catch(n){return B(n,t,e),Promise.resolve()}})();return Z[e]=i,i}(t,n);return(i=(()=>{}),{scope:o={},params:a=[]}={})=>{r.result=void 0,r.finished=!1;let s=P([o,...e]);if("function"==typeof r){let e=r(r,s).catch((e=>B(e,n,t)));r.finished?(Y(i,r.result,s,a,n),r.result=void 0):e.then((e=>{Y(i,e,s,a,n)})).catch((e=>B(e,n,t))).finally((()=>r.result=void 0))}}}(r,t,e);return W.bind(null,e,t,i)}var Z={};function Y(e,t,n,r,i){if(F&&"function"==typeof t){let o=t.apply(n,r);o instanceof Promise?o.then((t=>Y(e,t,n,r))).catch((e=>B(e,i,t))):e(o)}else e(t)}var J="x-";function G(e=""){return J+e}var Q={};function X(e,t){Q[e]=t}function ee(e,t,n){if(t=Array.from(t),e._x_virtualDirectives){let n=Object.entries(e._x_virtualDirectives).map((([e,t])=>({name:e,value:t}))),r=te(n);n=n.map((e=>r.find((t=>t.name===e.name))?{name:`x-bind:${e.name}`,value:`"${e.value}"`}:e)),t=t.concat(n)}let r={},i=t.map(se(((e,t)=>r[e]=t))).filter(ue).map(function(e,t){return({name:n,value:r})=>{let i=n.match(fe()),o=n.match(/:([a-zA-Z0-9\-:]+)/),a=n.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],s=t||e[n]||n;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:a.map((e=>e.replace(".",""))),expression:r,original:s}}}(r,n)).sort(pe);return i.map((t=>function(e,t){let n=()=>{},r=Q[t.type]||n,[i,o]=oe(e);!function(e,t,n){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(n)}(e,t.original,o);let a=()=>{e._x_ignore||e._x_ignoreSelf||(r.inline&&r.inline(e,t,i),r=r.bind(r,e,t,i),ne?re.get(ie).push(r):r())};return a.runCleanups=o,a}(e,t)))}function te(e){return Array.from(e).map(se()).filter((e=>!ue(e)))}var ne=!1,re=new Map,ie=Symbol();function oe(e){let t=[],[n,r]=function(e){let t=()=>{};return[n=>{let r=i(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach((e=>e()))}),e._x_effects.add(r),t=()=>{void 0!==r&&(e._x_effects.delete(r),o(r))},r},()=>{t()}]}(e);t.push(r);return[{Alpine:Ge,effect:n,cleanup:e=>t.push(e),evaluateLater:K.bind(K,e),evaluate:V.bind(V,e)},()=>t.forEach((e=>e()))]}var ae=(e,t)=>({name:n,value:r})=>(n.startsWith(e)&&(n=n.replace(e,t)),{name:n,value:r});function se(e=(()=>{})){return({name:t,value:n})=>{let{name:r,value:i}=le.reduce(((e,t)=>t(e)),{name:t,value:n});return r!==t&&e(r,t),{name:r,value:i}}}var le=[];function ce(e){le.push(e)}function ue({name:e}){return fe().test(e)}var fe=()=>new RegExp(`^${J}([^:^.]+)\\b`);var de="DEFAULT",_e=["ignore","ref","data","id","radio","tabs","switch","disclosure","menu","listbox","list","item","combobox","bind","init","for","mask","model","modelable","transition","show","if",de,"teleport"];function pe(e,t){let n=-1===_e.indexOf(e.type)?de:e.type,r=-1===_e.indexOf(t.type)?de:t.type;return _e.indexOf(n)-_e.indexOf(r)}function he(e,t,n={}){e.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0,composed:!0,cancelable:!0}))}var me=[],xe=!1;function ge(e=(()=>{})){return queueMicrotask((()=>{xe||setTimeout((()=>{ve()}))})),new Promise((t=>{me.push((()=>{e(),t()}))}))}function ve(){for(xe=!1;me.length;)me.shift()()}function ye(e,t){if("function"==typeof ShadowRoot&&e instanceof ShadowRoot)return void Array.from(e.children).forEach((e=>ye(e,t)));let n=!1;if(t(e,(()=>n=!0)),n)return;let r=e.firstElementChild;for(;r;)ye(r,t),r=r.nextElementSibling}function be(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var we=[],Ee=[];function ke(){return we.map((e=>e()))}function Ae(){return we.concat(Ee).map((e=>e()))}function Oe(e){we.push(e)}function Se(e){Ee.push(e)}function Ce(e,t=!1){return $e(e,(e=>{if((t?Ae():ke()).some((t=>e.matches(t))))return!0}))}function $e(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),e.parentElement)return $e(e.parentElement,t)}}function je(e,t=ye){!function(e){ne=!0;let t=Symbol();ie=t,re.set(t,[]);let n=()=>{for(;re.get(t).length;)re.get(t).shift()();re.delete(t)};e(n),ne=!1,n()}((()=>{t(e,((e,t)=>{ee(e,e.attributes).forEach((e=>e())),e._x_ignore&&t()}))}))}function Me(e,t){return Array.isArray(t)?Le(e,t.join(" ")):"object"==typeof t&&null!==t?function(e,t){let n=e=>e.split(" ").filter(Boolean),r=Object.entries(t).flatMap((([e,t])=>!!t&&n(e))).filter(Boolean),i=Object.entries(t).flatMap((([e,t])=>!t&&n(e))).filter(Boolean),o=[],a=[];return i.forEach((t=>{e.classList.contains(t)&&(e.classList.remove(t),a.push(t))})),r.forEach((t=>{e.classList.contains(t)||(e.classList.add(t),o.push(t))})),()=>{a.forEach((t=>e.classList.add(t))),o.forEach((t=>e.classList.remove(t)))}}(e,t):"function"==typeof t?Me(e,t()):Le(e,t)}function Le(e,t){return t=!0===t?t="":t||"",n=t.split(" ").filter((t=>!e.classList.contains(t))).filter(Boolean),e.classList.add(...n),()=>{e.classList.remove(...n)};var n}function Ne(e,t){return"object"==typeof t&&null!==t?function(e,t){let n={};return Object.entries(t).forEach((([t,r])=>{n[t]=e.style[t],t.startsWith("--")||(t=t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()),e.style.setProperty(t,r)})),setTimeout((()=>{0===e.style.length&&e.removeAttribute("style")})),()=>{Ne(e,n)}}(e,t):function(e,t){let n=e.getAttribute("style",t);return e.setAttribute("style",t),()=>{e.setAttribute("style",n||"")}}(e,t)}function Pe(e,t=(()=>{})){let n=!1;return function(){n?t.apply(this,arguments):(n=!0,e.apply(this,arguments))}}function Re(e,t,n={}){e._x_transition||(e._x_transition={enter:{during:n,start:n,end:n},leave:{during:n,start:n,end:n},in(n=(()=>{}),r=(()=>{})){ze(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},n,r)},out(n=(()=>{}),r=(()=>{})){ze(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},n,r)}})}function Te(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:Te(t)}function ze(e,t,{during:n,start:r,end:i}={},o=(()=>{}),a=(()=>{})){if(e._x_transitioning&&e._x_transitioning.cancel(),0===Object.keys(n).length&&0===Object.keys(r).length&&0===Object.keys(i).length)return o(),void a();let s,l,c;!function(e,t){let n,r,i,o=Pe((()=>{O((()=>{n=!0,r||t.before(),i||(t.end(),ve()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning}))}));e._x_transitioning={beforeCancels:[],beforeCancel(e){this.beforeCancels.push(e)},cancel:Pe((function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();o()})),finish:o},O((()=>{t.start(),t.during()})),xe=!0,requestAnimationFrame((()=>{if(n)return;let o=1e3*Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s","")),a=1e3*Number(getComputedStyle(e).transitionDelay.replace(/,.*/,"").replace("s",""));0===o&&(o=1e3*Number(getComputedStyle(e).animationDuration.replace("s",""))),O((()=>{t.before()})),r=!0,requestAnimationFrame((()=>{n||(O((()=>{t.end()})),ve(),setTimeout(e._x_transitioning.finish,o+a),i=!0)}))}))}(e,{start(){s=t(e,r)},during(){l=t(e,n)},before:o,end(){s(),c=t(e,i)},after:a,cleanup(){l(),c()}})}function Ie(e,t,n){if(-1===e.indexOf(t))return n;const r=e[e.indexOf(t)+1];if(!r)return n;if("scale"===t&&isNaN(r))return n;if("duration"===t){let e=r.match(/([0-9]+)ms/);if(e)return e[1]}return"origin"===t&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[r,e[e.indexOf(t)+2]].join(" "):r}X("transition",((e,{value:t,modifiers:n,expression:r},{evaluate:i})=>{"function"==typeof r&&(r=i(r)),r?function(e,t,n){Re(e,Me,""),{enter:t=>{e._x_transition.enter.during=t},"enter-start":t=>{e._x_transition.enter.start=t},"enter-end":t=>{e._x_transition.enter.end=t},leave:t=>{e._x_transition.leave.during=t},"leave-start":t=>{e._x_transition.leave.start=t},"leave-end":t=>{e._x_transition.leave.end=t}}[n](t)}(e,r,t):function(e,t,n){Re(e,Ne);let r=!t.includes("in")&&!t.includes("out")&&!n,i=r||t.includes("in")||["enter"].includes(n),o=r||t.includes("out")||["leave"].includes(n);t.includes("in")&&!r&&(t=t.filter(((e,n)=>nn>t.indexOf("out"))));let a=!t.includes("opacity")&&!t.includes("scale"),s=a||t.includes("opacity"),l=a||t.includes("scale"),c=s?0:1,u=l?Ie(t,"scale",95)/100:1,f=Ie(t,"delay",0),d=Ie(t,"origin","center"),_="opacity, transform",p=Ie(t,"duration",150)/1e3,h=Ie(t,"duration",75)/1e3,m="cubic-bezier(0.4, 0.0, 0.2, 1)";i&&(e._x_transition.enter.during={transformOrigin:d,transitionDelay:f,transitionProperty:_,transitionDuration:`${p}s`,transitionTimingFunction:m},e._x_transition.enter.start={opacity:c,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:"scale(1)"});o&&(e._x_transition.leave.during={transformOrigin:d,transitionDelay:f,transitionProperty:_,transitionDuration:`${h}s`,transitionTimingFunction:m},e._x_transition.leave.start={opacity:1,transform:"scale(1)"},e._x_transition.leave.end={opacity:c,transform:`scale(${u})`})}(e,n,t)})),window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,n,r){const i="visible"===document.visibilityState?requestAnimationFrame:setTimeout;let o=()=>i(n);t?e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(n):o():e._x_transition?e._x_transition.in(n):o():(e._x_hidePromise=e._x_transition?new Promise(((t,n)=>{e._x_transition.out((()=>{}),(()=>t(r))),e._x_transitioning.beforeCancel((()=>n({isFromCancelledTransition:!0})))})):Promise.resolve(r),queueMicrotask((()=>{let t=Te(e);t?(t._x_hideChildren||(t._x_hideChildren=[]),t._x_hideChildren.push(e)):i((()=>{let t=e=>{let n=Promise.all([e._x_hidePromise,...(e._x_hideChildren||[]).map(t)]).then((([e])=>e()));return delete e._x_hidePromise,delete e._x_hideChildren,n};t(e).catch((e=>{if(!e.isFromCancelledTransition)throw e}))}))})))};var De=!1;function qe(e,t=(()=>{})){return(...n)=>De?t(...n):e(...n)}function We(e,t,n,i=[]){switch(e._x_bindings||(e._x_bindings=r({})),e._x_bindings[t]=n,t=i.includes("camel")?t.toLowerCase().replace(/-(\w)/g,((e,t)=>t.toUpperCase())):t){case"value":!function(e,t){if("radio"===e.type)void 0===e.attributes.value&&(e.value=t),window.fromModel&&(e.checked=Be(e.value,t));else if("checkbox"===e.type)Number.isInteger(t)?e.value=t:Number.isInteger(t)||Array.isArray(t)||"boolean"==typeof t||[null,void 0].includes(t)?Array.isArray(t)?e.checked=t.some((t=>Be(t,e.value))):e.checked=!!t:e.value=String(t);else if("SELECT"===e.tagName)!function(e,t){const n=[].concat(t).map((e=>e+""));Array.from(e.options).forEach((e=>{e.selected=n.includes(e.value)}))}(e,t);else{if(e.value===t)return;e.value=t}}(e,n);break;case"style":!function(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles();e._x_undoAddedStyles=Ne(e,t)}(e,n);break;case"class":!function(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses();e._x_undoAddedClasses=Me(e,t)}(e,n);break;default:!function(e,t,n){[null,void 0,!1].includes(n)&&function(e){return!["aria-pressed","aria-checked","aria-expanded","aria-selected"].includes(e)}(t)?e.removeAttribute(t):(Fe(t)&&(n=t),function(e,t,n){e.getAttribute(t)!=n&&e.setAttribute(t,n)}(e,t,n))}(e,t,n)}}function Be(e,t){return e==t}function Fe(e){return["disabled","checked","required","readonly","hidden","open","selected","autofocus","itemscope","multiple","novalidate","allowfullscreen","allowpaymentrequest","formnovalidate","autoplay","controls","loop","muted","playsinline","default","ismap","reversed","async","defer","nomodule"].includes(e)}function Ve(e,t){var n;return function(){var r=this,i=arguments,o=function(){n=null,e.apply(r,i)};clearTimeout(n),n=setTimeout(o,t)}}function Ke(e,t){let n;return function(){let r=this,i=arguments;n||(e.apply(r,i),n=!0,setTimeout((()=>n=!1),t))}}var Ue={},He=!1;var Ze={};function Ye(e,t,n){let r=[];for(;r.length;)r.pop()();let i=Object.entries(t).map((([e,t])=>({name:e,value:t}))),o=te(i);i=i.map((e=>o.find((t=>t.name===e.name))?{name:`x-bind:${e.name}`,value:`"${e.value}"`}:e)),ee(e,i,n).map((e=>{r.push(e.runCleanups),e()}))}var Je={};var Ge={get reactive(){return r},get release(){return o},get effect(){return i},get raw(){return a},version:"3.10.5",flushAndStopDeferringMutations:function(){S=!1,$(C),C=[]},dontAutoEvaluateFunctions:function(e){let t=F;F=!1,e(),F=t},disableEffectScheduling:function(e){_=!1,e(),_=!0},setReactivityEngine:function(e){r=e.reactive,o=e.release,i=t=>e.effect(t,{scheduler:e=>{_?u(e):e()}}),a=e.raw},closestDataStack:N,skipDuringClone:qe,addRootSelector:Oe,addInitSelector:Se,addScopeToNode:M,deferMutations:function(){S=!0},mapAttributes:ce,evaluateLater:K,setEvaluator:function(e){U=e},mergeProxies:P,findClosest:$e,closestRoot:Ce,interceptor:T,transition:ze,setStyles:Ne,mutateDom:O,directive:X,throttle:Ke,debounce:Ve,evaluate:V,initTree:je,nextTick:ge,prefixed:G,prefix:function(e){J=e},plugin:function(e){e(Ge)},magic:D,store:function(e,t){if(He||(Ue=r(Ue),He=!0),void 0===t)return Ue[e];Ue[e]=t,"object"==typeof t&&null!==t&&t.hasOwnProperty("init")&&"function"==typeof t.init&&Ue[e].init(),R(Ue[e])},start:function(){var e;document.body||be("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + @endpush + + @slot('title') + @lang('pages.details.page_name') + @endslot + +
+
+
+
+

@lang('pages.details.about')

+ +
+ + {{ $configuration['symbol'] }} + + + + {{ $configuration['token'] }} + + + + {{ Format::readableCrypto((int) $configuration['totalPremine']) }} + + + + {{ Format::readableCrypto((int) $configuration['rewardPerBlock']) }} {{ $configuration['token'] }} + + + + {{ $configuration['blocktime'] }} s + + + + {{ $configuration['transactionsPerBlock'] }} + + + + {{ $configuration['forgers'] }} + +
+
+ +
+

@lang ('pages.details.network_details')

+ +
+ +
+ {{ $configuration['mainnetPrefix'] }} + {{ $configuration['devnetPrefix'] }} + {{ $configuration['testnetPrefix'] }} +
+
+ + + {{ $configuration['p2pPort'] }} + + + + {{ $configuration['apiPort'] }} + + + + {{ $configuration['webhookPort'] }} + + + + {{ $configuration['explorerPort'] }} + +
+
+
+ +
+ @can ('delete', $token) + + @endcan + +
+ + + +
+
+
+ +
+

@lang ('pages.details.important_links.title')

+ +
+ + +
+

@lang ('pages.details.important_links.explorer.title')

+ +
+ @foreach (NetworkTypeEnum::all() as $network) + @if ($token->network($network)->hasGenesis()) + + @endif + @endforeach +
+
+
+
+ +
+

@lang ('pages.details.useful_resources.title')

+ +
+ @php ($usefulResources = collect(trans('pages.details.useful_resources.links'))->splitIn(2)) + + @foreach ($usefulResources as $links) +
+ @foreach ($links as $url => $label) +
+ +
+ @endforeach +
+ @endforeach +
+
+ + @livewire('delete-token') +
+@endcomponent diff --git a/resources/views/app/tokens/edit.blade.php b/resources/views/app/tokens/edit.blade.php new file mode 100644 index 0000000..548386b --- /dev/null +++ b/resources/views/app/tokens/edit.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.app') + +@section('content') + +
+ +
+
+@endsection diff --git a/resources/views/app/tokens/index.blade.php b/resources/views/app/tokens/index.blade.php new file mode 100644 index 0000000..7a64271 --- /dev/null +++ b/resources/views/app/tokens/index.blade.php @@ -0,0 +1,9 @@ +@component('layouts.app', ['fullWidth' => true]) + + @section('content') + + @livewire('manage-tokens') + + @endsection + +@endcomponent diff --git a/resources/views/app/tokens/onboard.blade.php b/resources/views/app/tokens/onboard.blade.php new file mode 100644 index 0000000..878bf24 --- /dev/null +++ b/resources/views/app/tokens/onboard.blade.php @@ -0,0 +1,118 @@ +@extends('layouts.app') + +@section('content') + +
+
+

@lang('tokens.onboarding.page_header')

+

@lang('tokens.onboarding.page_subheader')

+
+ +
+
+
+
+ {{-- Customize Your Blockchain --}} + + + {{-- Connect Server Provider --}} + + + {{-- Server Configuration --}} + + + {{-- SSH Keys --}} + + + {{-- Invite Your Team --}} + + + {{-- Time to Deploy! --}} +
+ @if($token->onboarding()->fulfilled()) +
+ +
+ @else +
+ +
+ @endif +
! $token->onboarding()->fulfilled()])> + +

+ @lang('tokens.onboarding.deploy_your_blockchain_description') +

+
+
+
+ +
+ @can('delete', [Domain\Token\Models\Token::class, $token]) + + @endcan + + +
+ + + +
+
+
+
+
+@endsection diff --git a/resources/views/app/tokens/secure-shell-keys.blade.php b/resources/views/app/tokens/secure-shell-keys.blade.php new file mode 100644 index 0000000..48a5db7 --- /dev/null +++ b/resources/views/app/tokens/secure-shell-keys.blade.php @@ -0,0 +1,19 @@ +@component('layouts.token', ['token' => $token]) + @slot('title') + @lang('tokens.secure-shell-keys.page_header') + @endslot + +
+ @lang('tokens.secure-shell-keys.page_description') +
+ +
+
+ +
+ @livewire('manage-token-secure-shell-keys', ['token' => $token]) +
+@endcomponent diff --git a/resources/views/app/tokens/server-configuration.blade.php b/resources/views/app/tokens/server-configuration.blade.php new file mode 100644 index 0000000..6e7b754 --- /dev/null +++ b/resources/views/app/tokens/server-configuration.blade.php @@ -0,0 +1,13 @@ +@component('layouts.token', ['token' => $token]) + @slot('title') + @lang('tokens.server-configuration.page_header') + @endslot + +
+ @lang('tokens.server-configuration.page_description') +
+ +
+ @livewire('manage-server-configuration', ['token' => $token]) +
+@endcomponent diff --git a/resources/views/app/tokens/server-providers.blade.php b/resources/views/app/tokens/server-providers.blade.php new file mode 100644 index 0000000..288c2b4 --- /dev/null +++ b/resources/views/app/tokens/server-providers.blade.php @@ -0,0 +1,13 @@ +@component('layouts.token', ['token' => $token]) + @slot('title') + @lang('tokens.server-providers.page_header') + @endslot + +
+ @lang('tokens.server-providers.page_description') +
+ +
+ @livewire('manage-server-providers', ['token' => $token]) +
+@endcomponent diff --git a/resources/views/app/tokens/servers/create.blade.php b/resources/views/app/tokens/servers/create.blade.php new file mode 100644 index 0000000..6e72ae6 --- /dev/null +++ b/resources/views/app/tokens/servers/create.blade.php @@ -0,0 +1,8 @@ +@component('layouts.token', ['token' => $token]) + @slot('title') + @lang('actions.create_server') + @endslot + + @livewire('create-server', ['network' => $network]) + +@endcomponent diff --git a/resources/views/app/tokens/servers/index.blade.php b/resources/views/app/tokens/servers/index.blade.php new file mode 100644 index 0000000..a05abbc --- /dev/null +++ b/resources/views/app/tokens/servers/index.blade.php @@ -0,0 +1,13 @@ +@component('layouts.token', ['token' => $token]) + @push('scripts') + + @endpush + + @slot('title') + @lang('pages.token.servers.title') + @endslot + + + +@endcomponent + diff --git a/resources/views/app/tokens/servers/show.blade.php b/resources/views/app/tokens/servers/show.blade.php new file mode 100644 index 0000000..ab71a05 --- /dev/null +++ b/resources/views/app/tokens/servers/show.blade.php @@ -0,0 +1,7 @@ +@component('layouts.token', ['token' => $token, 'server' => $server]) + @slot('title') + @lang('pages.server.installation.page_name') + @endslot + + @livewire('server-deployment-tracker', ['token' => $token, 'serverId' => $server->id]) +@endcomponent diff --git a/resources/views/app/under-construction.blade.php b/resources/views/app/under-construction.blade.php new file mode 100644 index 0000000..7f13206 --- /dev/null +++ b/resources/views/app/under-construction.blade.php @@ -0,0 +1 @@ +Under Construction diff --git a/resources/views/app/user/settings/notifications.blade.php b/resources/views/app/user/settings/notifications.blade.php new file mode 100644 index 0000000..0e65665 --- /dev/null +++ b/resources/views/app/user/settings/notifications.blade.php @@ -0,0 +1,9 @@ +@component('layouts.app', ['fullWidth' => true]) + + @section('content') + + + + @endsection + +@endcomponent diff --git a/resources/views/app/user/settings/profile.blade.php b/resources/views/app/user/settings/profile.blade.php new file mode 100644 index 0000000..47b51f1 --- /dev/null +++ b/resources/views/app/user/settings/profile.blade.php @@ -0,0 +1,22 @@ +@component('layouts.user-settings') + + + + + + + + + + + + + + + +@endcomponent diff --git a/resources/views/app/user/settings/security.blade.php b/resources/views/app/user/settings/security.blade.php new file mode 100644 index 0000000..26aaffd --- /dev/null +++ b/resources/views/app/user/settings/security.blade.php @@ -0,0 +1,11 @@ +@component('layouts.user-settings', ['title' => trans('menus.user-settings.security')]) + @push('scripts') + + @endpush + + + + + + +@endcomponent diff --git a/resources/views/app/user/settings/ssh-keys.blade.php b/resources/views/app/user/settings/ssh-keys.blade.php new file mode 100644 index 0000000..d7cc445 --- /dev/null +++ b/resources/views/app/user/settings/ssh-keys.blade.php @@ -0,0 +1,9 @@ +@component('layouts.user-settings', ['title' => trans('menus.user-settings.ssh-keys')]) + @livewire('create-secure-shell-key') + + + + @livewire('manage-secure-shell-keys') + + @livewire('delete-secure-shell-key') +@endcomponent diff --git a/resources/views/app/user/settings/teams.blade.php b/resources/views/app/user/settings/teams.blade.php new file mode 100644 index 0000000..43b5c06 --- /dev/null +++ b/resources/views/app/user/settings/teams.blade.php @@ -0,0 +1,23 @@ +@component('layouts.app', ['fullWidth' => true, 'isLanding' => true]) + + @section('title', trans('pages.user-settings.teams.my_teams_title')) + + @section('content') + + + + + + + + + + + + + + @endsection +@endcomponent diff --git a/resources/views/components/blank.blade.php b/resources/views/components/blank.blade.php new file mode 100644 index 0000000..318d3b9 --- /dev/null +++ b/resources/views/components/blank.blade.php @@ -0,0 +1,3 @@ +
class('py-5 px-6 rounded-xl border border-theme-secondary-300') }}> + {{ $slot }} +
diff --git a/resources/views/components/blockchain-logo.blade.php b/resources/views/components/blockchain-logo.blade.php new file mode 100644 index 0000000..2e012c0 --- /dev/null +++ b/resources/views/components/blockchain-logo.blade.php @@ -0,0 +1,7 @@ +
+ @unless ($token->logo) + + @else +
+ @endunless +
diff --git a/resources/views/components/delete-modal.blade.php b/resources/views/components/delete-modal.blade.php new file mode 100644 index 0000000..2d0ca97 --- /dev/null +++ b/resources/views/components/delete-modal.blade.php @@ -0,0 +1,61 @@ +@props([ + 'actionMethod', + 'closeMethod', + 'title', + 'description', + 'image' => '/images/modal/question.svg', + 'canSubmit' => false, +]) + + + + {{ $title }} + + + +
+
+ {{ $title }} +
+ +
+ {{ $description }} +
+
+
+ + +
+ + + +
+
+
diff --git a/resources/views/components/divider.blade.php b/resources/views/components/divider.blade.php new file mode 100644 index 0000000..7f28f39 --- /dev/null +++ b/resources/views/components/divider.blade.php @@ -0,0 +1,10 @@ +@props ([ + 'spacing' => '12' +]) + +
class('border-t border-theme-secondary-300 border-dashed')->class([ + '4' => 'pt-4 mt-4', + '6' => 'pt-6 mt-6', + '8' => 'pt-8 mt-8', + '12' => 'pt-12 mt-12', +][$spacing] ?? 'pt-12 mt-12') }}> diff --git a/resources/views/components/grid.blade.php b/resources/views/components/grid.blade.php new file mode 100644 index 0000000..7124405 --- /dev/null +++ b/resources/views/components/grid.blade.php @@ -0,0 +1,14 @@ +
+
+

{{ $title }}

+
{{ $description }}
+
+ +
+
+
+ {{ $slot }} +
+
+
+
diff --git a/resources/views/components/griddy.blade.php b/resources/views/components/griddy.blade.php new file mode 100644 index 0000000..c75054e --- /dev/null +++ b/resources/views/components/griddy.blade.php @@ -0,0 +1,13 @@ +
+
+

{{ $title }}

+
+ +
+
+
+ {{ $slot }} +
+
+
+
diff --git a/resources/views/components/home/active-servers/action-dropdown.blade.php b/resources/views/components/home/active-servers/action-dropdown.blade.php new file mode 100644 index 0000000..f2201e9 --- /dev/null +++ b/resources/views/components/home/active-servers/action-dropdown.blade.php @@ -0,0 +1,101 @@ +@props([ + 'server', +]) + +
+ @if ($server->isProvisioned() || $server->isFailed()) + @canany(['start', 'stop', 'restart', 'rename', 'delete'], $server) +
+ + @if ($server->isProvisioned()) + @can ('rename', $server) + + @endcan + + @can ('start', $server) + + @endcan + + @can ('stop', $server) + + @endcan + + @can ('restart', $server) + + @endcan + + + @endif + + @can ('delete', $server) + + @endcan + +
+ @endcanany + @endif +
diff --git a/resources/views/components/home/active-servers/desktop-table.blade.php b/resources/views/components/home/active-servers/desktop-table.blade.php new file mode 100644 index 0000000..98df0b9 --- /dev/null +++ b/resources/views/components/home/active-servers/desktop-table.blade.php @@ -0,0 +1,123 @@ +@props([ + 'sortBy', + 'sortDirection', + 'servers', +]) + + diff --git a/resources/views/components/home/active-servers/desktop-tabs.blade.php b/resources/views/components/home/active-servers/desktop-tabs.blade.php new file mode 100644 index 0000000..5f5cfc7 --- /dev/null +++ b/resources/views/components/home/active-servers/desktop-tabs.blade.php @@ -0,0 +1,44 @@ +@props([ + 'networks', + 'default', +]) + + diff --git a/resources/views/components/home/active-servers/mobile-accordion.blade.php b/resources/views/components/home/active-servers/mobile-accordion.blade.php new file mode 100644 index 0000000..0174c41 --- /dev/null +++ b/resources/views/components/home/active-servers/mobile-accordion.blade.php @@ -0,0 +1,144 @@ +@props([ + 'servers', +]) + +
+ @foreach ($servers as $server) + @php($isProvisioned = $server->isProvisioned()) + @php($isFailed = $server->isFailed()) + @php($pathShow = $server->pathShow()) + + + + + {{ $server->name }} + + + +
+
+
+ @lang('tokens.networks.table_status') +
+ +
+
+
+ @lang('tokens.networks.table_ip_address') + @if($server->ip_address) +
+ {{ $server->ip_address }} + +
+ @else + @lang('tokens.networks.server_unavailable') + @endif +
+
+ @lang('tokens.networks.table_size') + {{ $server->plan->disk }} +
+
+ @lang('tokens.networks.table_region') + {{ $server->region->name }} +
+
+ @lang('tokens.networks.table_preset') + @if($isProvisioned && PresetTypeEnum::isExplorer($server->preset)) + + @else + {{ ucfirst($server->preset) }} + @endif +
+
+
+
+ @if ($isProvisioned) +
+ @if ($server->hasEverHadStatus('provisioning') || $isFailed) + @can('delete', [Domain\Server\Models\Server::class, $server]) + + @endcan + @endif + + @can('rename', [Domain\Server\Models\Server::class, $server]) + + @endcan +
+ + @canany(['start', 'stop', 'restart'], [Domain\Server\Models\Server::class, $server]) +
+ + @can('start', [Domain\Server\Models\Server::class, $server]) + + @endcan + @can('stop', [Domain\Server\Models\Server::class, $server]) + + @endcan + @can('restart', [Domain\Server\Models\Server::class, $server]) + + @endcan + +
+ @endcanany + @endif +
+
+
+
+ @endforeach +
diff --git a/resources/views/components/home/active-servers/mobile-dropdown.blade.php b/resources/views/components/home/active-servers/mobile-dropdown.blade.php new file mode 100644 index 0000000..05d96c5 --- /dev/null +++ b/resources/views/components/home/active-servers/mobile-dropdown.blade.php @@ -0,0 +1,64 @@ +@props([ + 'selected', + 'networks', +]) + +
+ + +
+
+
+ +
+ +
+ +
+
+ +
@lang('tokens.'.$selected->name)
+
+
+ +
+ @foreach ($networks as $network) + + @endforeach +
+
+
diff --git a/resources/views/components/home/active-servers/type-filter.blade.php b/resources/views/components/home/active-servers/type-filter.blade.php new file mode 100644 index 0000000..8a964c7 --- /dev/null +++ b/resources/views/components/home/active-servers/type-filter.blade.php @@ -0,0 +1,10 @@ +@props([ + 'mobile' => false, +]) + + diff --git a/resources/views/components/modals/expired-link-modal.blade.php b/resources/views/components/modals/expired-link-modal.blade.php new file mode 100644 index 0000000..3438362 --- /dev/null +++ b/resources/views/components/modals/expired-link-modal.blade.php @@ -0,0 +1,23 @@ +@props ([ + 'wire', + 'title', + 'message', +]) + + + + {{ $title }} + + + +
+ {{ $title }} +
+ +

{{ $message }}

+
+
diff --git a/resources/views/components/modals/invalid-link-modal.blade.php b/resources/views/components/modals/invalid-link-modal.blade.php new file mode 100644 index 0000000..2f80513 --- /dev/null +++ b/resources/views/components/modals/invalid-link-modal.blade.php @@ -0,0 +1,23 @@ +@props ([ + 'wire', + 'title', + 'message', +]) + + + + {{ $title }} + + + +
+ {{ $title }} +
+ +

{{ $message }}

+
+
diff --git a/resources/views/components/onboard-step.blade.php b/resources/views/components/onboard-step.blade.php new file mode 100644 index 0000000..55780f8 --- /dev/null +++ b/resources/views/components/onboard-step.blade.php @@ -0,0 +1,39 @@ +@php($isCompleted = $token->onboarding()->completed($name)) +@php($isAvailable = $token->onboarding()->available($name)) + +
+ @if($isCompleted) +
+ +
+ @elseif($isAvailable) +
+ +
+ @else +
+ +
+ @endif +
+
+ @if($isCompleted || $isAvailable) + + {{ $title }} + + @else + + {{ $title }} + + @endif + @if($optional ?? false) + Optional + @endif +
+
{{ $description }}
+
+
diff --git a/resources/views/components/pending-invitations.blade.php b/resources/views/components/pending-invitations.blade.php new file mode 100644 index 0000000..bdf59db --- /dev/null +++ b/resources/views/components/pending-invitations.blade.php @@ -0,0 +1,160 @@ +@if($invitationsCount) +
+
+

@lang('pages.user-settings.teams.pending_title')

+ @lang('pages.user-settings.teams.pending_description') +
+ + @if (session('status') === TokenInvitationController::ALERT_STATUS) + + @endif + +
+
    + @foreach($currentUser->invitations as $invitation) +
  • +
    +
    +
    + @lang('tables.blockchain_name') +
    +
    + {{ $invitation->token->name }} +
    +
    +
    +
    + @lang('tables.invited_by') +
    +
    + {{ $invitation->token->user->name }} +
    +
    +
    +
    + @lang('tables.role') +
    +
    + +
    +
    +
    +
    + @lang('tables.date_invited') +
    +
    + {{ $invitation->token->created_at_local->format(DateFormat::DATE) }} +
    +
    +
    + +
    + + @lang('actions.accept') + + + +
    + @unless ($loop->last) + + @endunless +
  • + @endforeach +
+ + +
+
+
+@endif diff --git a/resources/views/components/profile/keys/desktop.blade.php b/resources/views/components/profile/keys/desktop.blade.php new file mode 100644 index 0000000..e913dfb --- /dev/null +++ b/resources/views/components/profile/keys/desktop.blade.php @@ -0,0 +1,47 @@ +@props (['keys']) + + + + + + {{ trans('tables.name') }} + + + + {{ trans('tables.fingerprint') }} + + + + {{ trans('tables.date_added') }} + + + + + + + + @foreach ($keys as $key) + + + + {{ $key->name }} + + + + + + {{ $key->fingerprint }} + + + + {{ $key->created_at_local->format(DateFormat::DATE) }} + + + + + + @endforeach + + diff --git a/resources/views/components/profile/keys/item.blade.php b/resources/views/components/profile/keys/item.blade.php new file mode 100644 index 0000000..4984a06 --- /dev/null +++ b/resources/views/components/profile/keys/item.blade.php @@ -0,0 +1,11 @@ +@props (['label']) + +
class('flex justify-between space-x-6') }}> +
+ {{ $label }} +
+ +
+ {{ $slot }} +
+
diff --git a/resources/views/components/profile/keys/mobile.blade.php b/resources/views/components/profile/keys/mobile.blade.php new file mode 100644 index 0000000..5d7ae6e --- /dev/null +++ b/resources/views/components/profile/keys/mobile.blade.php @@ -0,0 +1,32 @@ +@props (['keys']) + +
+ @foreach ($keys as $key) +
+ + + {{ $key->name }} + + + + + + {{ $key->fingerprint }} + + + + + {{ $key->created_at_local->format(DateFormat::DATE) }} + + +
+ +
+
+ @endforeach +
diff --git a/resources/views/components/server-providers/desktop.blade.php b/resources/views/components/server-providers/desktop.blade.php new file mode 100644 index 0000000..4ba7946 --- /dev/null +++ b/resources/views/components/server-providers/desktop.blade.php @@ -0,0 +1,52 @@ +@props (['providers']) + + + + + + {{ trans('tables.name') }} + + + + {{ trans('tables.date_added') }} + + + + + + + + @foreach ($providers as $provider) + + +
+ + + + + + {{ $provider->name }} + +
+
+ + {{ $provider->created_at_local->format(DateFormat::DATE) }} + + +
+ +
+
+
+ @endforeach + +
diff --git a/resources/views/components/server-providers/item.blade.php b/resources/views/components/server-providers/item.blade.php new file mode 100644 index 0000000..4984a06 --- /dev/null +++ b/resources/views/components/server-providers/item.blade.php @@ -0,0 +1,11 @@ +@props (['label']) + +
class('flex justify-between space-x-6') }}> +
+ {{ $label }} +
+ +
+ {{ $slot }} +
+
diff --git a/resources/views/components/server-providers/mobile.blade.php b/resources/views/components/server-providers/mobile.blade.php new file mode 100644 index 0000000..b57098b --- /dev/null +++ b/resources/views/components/server-providers/mobile.blade.php @@ -0,0 +1,35 @@ +@props (['providers']) + +
+ @foreach ($providers as $provider) +
+ +
+ + + + + + {{ $provider->name }} + +
+
+ + + {{ $provider->created_at_local->format(DateFormat::DATE) }} + + + @can ('delete', $provider) +
+ +
+ @endcan +
+ @endforeach +
diff --git a/resources/views/components/server-providers/select.blade.php b/resources/views/components/server-providers/select.blade.php new file mode 100644 index 0000000..5dd89c3 --- /dev/null +++ b/resources/views/components/server-providers/select.blade.php @@ -0,0 +1,61 @@ +@props ([ + 'provider', + 'enabled', +]) + +@if ($enabled) +
+
+
+
+ +
+ +
+
+@else +
+
+
+
+ +
+ {{ trans('actions.coming_soon') }} +
+
+@endif diff --git a/resources/views/components/servers/status.blade.php b/resources/views/components/servers/status.blade.php new file mode 100644 index 0000000..72e8bc0 --- /dev/null +++ b/resources/views/components/servers/status.blade.php @@ -0,0 +1,21 @@ +@props ([ + 'server' +]) + +
class('flex items-center space-x-2') }}> + @if ($server->isOffline()) + + {{ trans('pages.server.status.offline') }} + @elseif ($server->isFailed()) + + {{ trans('pages.server.status.failed') }} + @elseif ($server->isProvisioned()) + + {{ trans('pages.server.status.online') }} + @else + + + {{ trans('pages.server.status.provisioning') }} + + @endif +
diff --git a/resources/views/components/sort-by-button.blade.php b/resources/views/components/sort-by-button.blade.php new file mode 100644 index 0000000..c87fbb2 --- /dev/null +++ b/resources/views/components/sort-by-button.blade.php @@ -0,0 +1,11 @@ + diff --git a/resources/views/components/token-sidebar-links.blade.php b/resources/views/components/token-sidebar-links.blade.php new file mode 100644 index 0000000..d9bae8b --- /dev/null +++ b/resources/views/components/token-sidebar-links.blade.php @@ -0,0 +1,51 @@ + + + + + + +@canany(['createCollaborator', 'deleteCollaborator'], [Domain\Token\Models\Token::class, $token]) + +@endcanany + + + + + + diff --git a/resources/views/components/token-slider-placeholder.blade.php b/resources/views/components/token-slider-placeholder.blade.php new file mode 100644 index 0000000..4019d19 --- /dev/null +++ b/resources/views/components/token-slider-placeholder.blade.php @@ -0,0 +1,12 @@ + +
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/components/token-slider.blade.php b/resources/views/components/token-slider.blade.php new file mode 100644 index 0000000..24c75e0 --- /dev/null +++ b/resources/views/components/token-slider.blade.php @@ -0,0 +1,41 @@ +
+ + @foreach ($tokens as $token) + +
+
+ +
{{ $token->name }}
+
+ + + {{ $token->servers_count }} + + + + @if ($token->hasProvisionedGenesisServer()) + + @else + + @endif + {{ $token->hasProvisionedGenesisServer() ? trans('pages.manage-tokens.status_deployed_short') : trans('pages.manage-tokens.status_pending_short') }} + +
+
+ + +
+
+ @endforeach + @for ($i = $tokens->count(); $i < 4; $i++) + + @endfor +
+
diff --git a/resources/views/components/tokens/details-item.blade.php b/resources/views/components/tokens/details-item.blade.php new file mode 100644 index 0000000..2399932 --- /dev/null +++ b/resources/views/components/tokens/details-item.blade.php @@ -0,0 +1,9 @@ +@props (['title']) + +
class('flex justify-between py-3') }}> +
{{ $title }}:
+ +
+ {{ $slot }} +
+
diff --git a/resources/views/components/tokens/heading.blade.php b/resources/views/components/tokens/heading.blade.php new file mode 100644 index 0000000..419989f --- /dev/null +++ b/resources/views/components/tokens/heading.blade.php @@ -0,0 +1,16 @@ +@props ([ + 'title', + 'description', + 'link' => null, +]) + +
+

{{ $title }}

+

{{ $description }}

+ + @if ($link) +
+ +
+ @endif +
diff --git a/resources/views/components/tokens/onboard-buttons.blade.php b/resources/views/components/tokens/onboard-buttons.blade.php new file mode 100644 index 0000000..7b0ad1c --- /dev/null +++ b/resources/views/components/tokens/onboard-buttons.blade.php @@ -0,0 +1,50 @@ +
class('flex flex-col-reverse sm:flex-row justify-end items-center w-full sm:space-x-3') }}> + @if($showCancel ?? true) + + @lang('actions.cancel') + + @endif + + @if($step ?? false) + @if (! $token || $token->onboarding()->isStep(Format::stepTitle($step))) + @unless($submitButton ?? false) + + {{ $title ?? trans('actions.save_continue') }} + + @else +
diff --git a/resources/views/components/tokens/sidebar-divider.blade.php b/resources/views/components/tokens/sidebar-divider.blade.php new file mode 100644 index 0000000..6e87577 --- /dev/null +++ b/resources/views/components/tokens/sidebar-divider.blade.php @@ -0,0 +1 @@ +
class('border-t border-dashed border-theme-secondary-300 mr-4') }}>
diff --git a/resources/views/components/tokens/step-indicator.blade.php b/resources/views/components/tokens/step-indicator.blade.php new file mode 100644 index 0000000..fd4db63 --- /dev/null +++ b/resources/views/components/tokens/step-indicator.blade.php @@ -0,0 +1,11 @@ +@props ([ + 'active', + 'current', +]) + +
$active === $current, + 'text-theme-secondary-500 border-theme-warning-500' => $active > $current, + 'text-theme-secondary-500 border-theme-secondary-200' => $active < $current, +])>
diff --git a/resources/views/components/tokens/subheading.blade.php b/resources/views/components/tokens/subheading.blade.php new file mode 100644 index 0000000..f8aed40 --- /dev/null +++ b/resources/views/components/tokens/subheading.blade.php @@ -0,0 +1,36 @@ +@props ([ + 'title', + 'description' => null, + 'fields' => null, + 'wire' => null, +]) + +
+
+

+ {{ $title }} +

+ + +
+ + @if ($description) +
+

{{ $description }}

+
+ @endif +
diff --git a/resources/views/components/truncated-cell.blade.php b/resources/views/components/truncated-cell.blade.php new file mode 100644 index 0000000..a98887b --- /dev/null +++ b/resources/views/components/truncated-cell.blade.php @@ -0,0 +1,6 @@ +
merge(['class' => 'relative']) }}> + + {{ $slot }} + + +
diff --git a/resources/views/components/user-teams.blade.php b/resources/views/components/user-teams.blade.php new file mode 100644 index 0000000..b740a65 --- /dev/null +++ b/resources/views/components/user-teams.blade.php @@ -0,0 +1,154 @@ +
+
+

@lang('pages.user-settings.teams.my_teams_title')

+ @lang('pages.user-settings.teams.my_teams_description') +
+ + @if (session('status') === LeaveTeamModal::ALERT_STATUS) + + @endif + +
+ @if($currentUser->tokens->isNotEmpty()) +
+
    + @foreach($currentUser->tokens as $token) +
  • +
    +
    +
    + +
    +
    + {{ $token->name }} +
    +
    +
    +
    + @lang('tables.role') +
    +
    + +
    +
    +
    +
    + @lang('tables.date_invited') +
    +
    + {{ $token->created_at_local->format(DateFormat::DATE) }} +
    +
    +
    + +
    + ownsToken($token)) + data-tippy-content="{{ trans('pages.user-settings.teams.leave_owner') }}" + data-tippy-trigger="mouseenter" + @endif + > + + +
    + @unless ($loop->last) + + @endunless +
  • + @endforeach +
+ + +
+ @else +
+
+ @lang('pages.user-settings.no_current_teams') +
+ +
+ + + +
+
+ @endif +
+
diff --git a/resources/views/components/welcome-screens.blade.php b/resources/views/components/welcome-screens.blade.php new file mode 100644 index 0000000..823d514 --- /dev/null +++ b/resources/views/components/welcome-screens.blade.php @@ -0,0 +1,147 @@ +
+ + +
+
+

{{ trans('pages.welcome.intro.title') }}

+
+ +
+ +
+ +
+

{{ trans('pages.welcome.intro.description') }}

+
+
+ +
+ + @for ($i = 0; $i < 3; $i++) + +
+

{{ trans('pages.welcome.slide'.$i.'.title') }}

+
+ +
+ +
+ +
+

{{ trans('pages.welcome.slide'.$i.'.description') }}

+
+
+ @endfor + + {{-- Video slide --}} + {{-- +
+

{{ trans('pages.welcome.slide3.title') }}

+
+ +
+ +
+ +
+

{{ trans('pages.welcome.slide3.description') }}

+
+
--}} +
+
+
+ + +
+
+ +
+ +
+ + + +
+
+ +
+
+ @for ($i = 0; $i < 3; $i++) + + @endfor +
+ +
+ + + + + +
+
+
+
+
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php new file mode 100644 index 0000000..ae243fc --- /dev/null +++ b/resources/views/layouts/app.blade.php @@ -0,0 +1,84 @@ + + + + + + + + + @auth + + @livewire('notifications-indicator') + + + + + + @endauth + + + +
+ {{ config('app.name') }} +
+ + +
+
+
+ + + + +
+ diff --git a/resources/views/layouts/server.blade.php b/resources/views/layouts/server.blade.php new file mode 100644 index 0000000..a2ddcaa --- /dev/null +++ b/resources/views/layouts/server.blade.php @@ -0,0 +1,45 @@ +@extends('layouts.app') + +@section('content') + +
+

{{ $server->name }}

+
+ +
+
+
+
+
+
+ + @lang('menus.menu') +
+ + +
+
+ +
+
+ +
+ {{ $slot }} +
+
+
+
+
+@endsection diff --git a/resources/views/layouts/token.blade.php b/resources/views/layouts/token.blade.php new file mode 100644 index 0000000..1491b48 --- /dev/null +++ b/resources/views/layouts/token.blade.php @@ -0,0 +1,67 @@ +@extends('layouts.app') + +@push('scripts') + +@endpush + +@section('content') + +
+ @unless($token->canBeEdited()) +
+
+
+ +
+ +
+ + @lang('tokens.token') + + + + {{ $token->name }} + +
+
+ +
+ @endunless + +
+ @unless($token->canBeEdited()) + + + + + + @endunless +
+
+ +
+

{{ $title ?? '' }}

+
{{ $slot }}
+
+
+@endsection diff --git a/resources/views/layouts/user-settings.blade.php b/resources/views/layouts/user-settings.blade.php new file mode 100644 index 0000000..18a05dd --- /dev/null +++ b/resources/views/layouts/user-settings.blade.php @@ -0,0 +1,29 @@ +@extends('layouts.app') + +@section('content') + + + +
+
+ + + + + + + +
+ + @if (($title ?? null) !== false) +

{{ $title ?? trans('pages.user-settings.page_name') }}

+ @endif + +
{{ $slot }}
+
+
+@endsection diff --git a/resources/views/livewire/active-servers.blade.php b/resources/views/livewire/active-servers.blade.php new file mode 100644 index 0000000..0895a30 --- /dev/null +++ b/resources/views/livewire/active-servers.blade.php @@ -0,0 +1,80 @@ +@php($hasSecureShellKeys = $selectedToken->hasSecureShellKeys()) +@php($hasServerProviders = $selectedToken->hasServerProviders()) +@php($needsServerConfiguration = $selectedToken->needsServerConfiguration()) +@php($hasGenesis = $selectedNetwork->hasGenesis()) + +@if(!$hasSecureShellKeys || !$hasServerProviders || $needsServerConfiguration) + + {!! trans('tokens.networks.onboarding_incomplete', ['route' => route('tokens.welcome', $selectedToken)]) !!} + +@endif + +@if($hasSecureShellKeys && $hasServerProviders && $selectedToken->hasAuthorizedKeys() && ! $needsServerConfiguration) +
+ @if($title) +

{{ $title }}

+ @endif + + + + + +
+ +
+ + @if($selectedNetworkServers->count() > 0) + @if(! $hasGenesis) + + @endif + +
+ +
+ +
+ +
+ + + @else +
+ @lang('tokens.networks.no_servers_created') +
+ @endif + + @if($selectedToken->allows($this->user, 'server:create') && $selectedToken->hasAnyIndexedServerProvider()) + @if($hasGenesis && !$selectedNetwork->hasProvisionedGenesis()) +
+ @lang('pages.manage-tokens.no_provisioned_genesis') +
+ @else +
+ + @lang('pages.manage-tokens.add_server_description') +
+ @endif + @endif +
+@endif + +@livewire('delete-server', ['token' => $selectedToken, 'network' => $selectedNetwork], key('delete-server-' . $selectedToken->id . '-' . $selectedNetwork->id)) + +@livewire('rename-server', ['token' => $selectedToken, 'network' => $selectedNetwork], key('rename-server-' . $selectedToken->id . '-' . $selectedNetwork->id)) diff --git a/resources/views/livewire/collaborator-permissions-modal.blade.php b/resources/views/livewire/collaborator-permissions-modal.blade.php new file mode 100644 index 0000000..913d570 --- /dev/null +++ b/resources/views/livewire/collaborator-permissions-modal.blade.php @@ -0,0 +1,32 @@ +
+ @if ($this->modalShown) + + @slot('title') @lang('pages.user-settings.role_permissions_title') @endslot + + @slot('description') +
+
+ @foreach($this->availablePermissions as $permission) +
+ @if($this->permissions === [] || in_array($permission, $this->permissions)) + + @else + + @endif + + {{ trans('pages.collaborators.permissions.'.$permission) }} +
+ @endforeach +
+
+ @endslot + + @slot('buttons') +
+ +
+ @endslot +
+ @endif +
+ diff --git a/resources/views/livewire/create-secure-shell-key.blade.php b/resources/views/livewire/create-secure-shell-key.blade.php new file mode 100644 index 0000000..25f4dd3 --- /dev/null +++ b/resources/views/livewire/create-secure-shell-key.blade.php @@ -0,0 +1,15 @@ +
+

@lang('pages.user-settings.create_ssh_title')

+

@lang('pages.user-settings.create_ssh_description')

+ +
+
+ + +
+ +
+ +
+
+
diff --git a/resources/views/livewire/create-server.blade.php b/resources/views/livewire/create-server.blade.php new file mode 100644 index 0000000..d848978 --- /dev/null +++ b/resources/views/livewire/create-server.blade.php @@ -0,0 +1,136 @@ +
+ @push('scripts') + + @endpush + +
+ +
+ +
+ + + @foreach ($this->getUniqueProviders() as $providerOption) + +
+
+
+
+
+ +
+
+
+ @endforeach +
+
+ + @if ($this->hasMultipleKeysOnProvider) +
+ + + + @foreach($this->providerEntries as $option) + @if ($option->allIndexed()) + + @else + + @endif + @endforeach + +
+ @endif + + @if($network->servers_count > 0) +
+ +
+
+
+ @foreach($this->presets as $presetOption) +
+
+ {{ Str::title($presetOption) }} +
+
+ +
+
+ @endforeach +
+
+ @endif + +
+ @if($preset === PresetTypeEnum::FORGER) + + @lang('forms.create_server.passphrases_warning') + +
+ +
+
+ +
+ @endif +
+ + @if(! empty($selectedProvider)) +
+ + + @endforeach + +
+ +
+ + + + @if ($this->region) + @foreach($this->formattedPlans as $option) + + @endforeach + @endif + +
+ @endif + +
+ + + +
+
diff --git a/resources/views/livewire/create-token-modal.blade.php b/resources/views/livewire/create-token-modal.blade.php new file mode 100644 index 0000000..a1c5d64 --- /dev/null +++ b/resources/views/livewire/create-token-modal.blade.php @@ -0,0 +1,44 @@ +
+ @if ($this->token) + + +
+
+ {{ trans('actions.create_token') }} +
+ + + {{ trans('tokens.create_token_modal.description1') }} + + +
+ +
+ +

{{ trans('tokens.create_token_modal.description2') }}

+
+
+ + +
+ + + +
+
+
+ @endif +
diff --git a/resources/views/livewire/decline-invitation-modal.blade.php b/resources/views/livewire/decline-invitation-modal.blade.php new file mode 100644 index 0000000..8b17718 --- /dev/null +++ b/resources/views/livewire/decline-invitation-modal.blade.php @@ -0,0 +1,39 @@ +
+ @if ($this->invitationId) + + @slot('title') @lang('pages.user-settings.teams.decline_title') @endslot + + @slot('description') +
+
+ +
+ + +
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot +
+ @endif +
+ diff --git a/resources/views/livewire/delete-collaborator.blade.php b/resources/views/livewire/delete-collaborator.blade.php new file mode 100644 index 0000000..28fc57b --- /dev/null +++ b/resources/views/livewire/delete-collaborator.blade.php @@ -0,0 +1,28 @@ +
+ @if($this->collaboratorId) + + @slot('title') + @lang('tokens.remove_collaborator') + @endslot + + @slot('description') +
+
+ +
+
@lang('tokens.are_you_sure_you_want_to_delete_collaborator')
+
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot +
+ @endif +
diff --git a/resources/views/livewire/delete-secure-shell-key.blade.php b/resources/views/livewire/delete-secure-shell-key.blade.php new file mode 100644 index 0000000..2821cd0 --- /dev/null +++ b/resources/views/livewire/delete-secure-shell-key.blade.php @@ -0,0 +1,12 @@ +
+ @if ($this->keyId) + + @endif +
diff --git a/resources/views/livewire/delete-server-provider.blade.php b/resources/views/livewire/delete-server-provider.blade.php new file mode 100644 index 0000000..1eaffbd --- /dev/null +++ b/resources/views/livewire/delete-server-provider.blade.php @@ -0,0 +1,65 @@ +
+ @if ($this->serverProviderId && $this->modalShown) + + +
+
+ {{ trans('tokens.server-providers.remove_server_provider_title') }} +
+ +

+ {{ trans('tokens.server-providers.remove_server_provider_description') }} +

+ + + + +
+
+ + +
+ + + +
+
+
+ @endif +
diff --git a/resources/views/livewire/delete-server.blade.php b/resources/views/livewire/delete-server.blade.php new file mode 100644 index 0000000..5982569 --- /dev/null +++ b/resources/views/livewire/delete-server.blade.php @@ -0,0 +1,28 @@ +
+ @if($this->serverId) + + @slot('title') + @lang('tokens.servers.remove_server_title') + @endslot + + @slot('description') +
+
+ +
+
@lang('tokens.servers.remove_server_description')
+
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot +
+ @endif +
diff --git a/resources/views/livewire/delete-token.blade.php b/resources/views/livewire/delete-token.blade.php new file mode 100644 index 0000000..9b6c18a --- /dev/null +++ b/resources/views/livewire/delete-token.blade.php @@ -0,0 +1,69 @@ +
+ @if($this->tokenId) + + @slot('title') + @lang('actions.delete_token') + @endslot + + @slot('description') +
+ @lang('tokens.delete_token_modal.description') +
+
+
+ @foreach($this->options as $key => $option) + @if ($key === 'blockchain') +
+ @else +
+ @endif +
+
+
+ selectedOptions) ? 'checked' : '' }} + @if($this->shouldBeDisabled($key)) disabled @endif + /> +
+
+ +

{{ $option }}

+
+
+
+
+ @endforeach +
+
+ +
+ @lang('tokens.delete_token_modal.name') +
+ +
+ +
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot + + @endif +
diff --git a/resources/views/livewire/deploy-blockchain.blade.php b/resources/views/livewire/deploy-blockchain.blade.php new file mode 100644 index 0000000..bc140d8 --- /dev/null +++ b/resources/views/livewire/deploy-blockchain.blade.php @@ -0,0 +1,54 @@ +
+ @if($this->tokenId) + + @slot('title') + @lang('actions.deploy_blockchain') + @endslot + + @slot('description') +
+ @lang('tokens.deploy_blockchain_modal.description') +
+
+
+ @foreach($this->options as $key => $option) +
+
+
+
+ selectedOption === $key ? 'checked' : '' }} + /> +
+ +
+ +

{{ $option }}

+
+
+
+
+ @endforeach +
+
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot +
+ @endif +
diff --git a/resources/views/livewire/download-install-script.blade.php b/resources/views/livewire/download-install-script.blade.php new file mode 100644 index 0000000..dfa19ea --- /dev/null +++ b/resources/views/livewire/download-install-script.blade.php @@ -0,0 +1,30 @@ +
+ @php($availableNetworks = $this->availableNetworks()) + @php($hasAvailableNetworks = count($availableNetworks) > 0) + + + + + + @lang('actions.install_script') + +
+ @foreach($availableNetworks as $network) +
+ {{ ucfirst($network) }} +
+ @endforeach +
+
+
diff --git a/resources/views/livewire/invite-collaborator.blade.php b/resources/views/livewire/invite-collaborator.blade.php new file mode 100644 index 0000000..983034c --- /dev/null +++ b/resources/views/livewire/invite-collaborator.blade.php @@ -0,0 +1,47 @@ +
+

{{ trans('pages.collaborators.send_invitation_title') }}

+

{{ trans('pages.collaborators.send_invitation_description', ['appName' => config('app.name')]) }}

+ +
+
+ +
+ + + +
+ + @lang('forms.invite_collaborator.permissions') + +
+ @lang('actions.select_all') + @lang('actions.deselect_all') +
+
+ +
+ @foreach ($this->availablePermissions as $permission) +
+ +
+ @endforeach +
+ +
+ @error('permissions') +

{{ $message }}

+ @enderror +
+
+ +
+ +
+ +
diff --git a/resources/views/livewire/leave-team-modal.blade.php b/resources/views/livewire/leave-team-modal.blade.php new file mode 100644 index 0000000..938d014 --- /dev/null +++ b/resources/views/livewire/leave-team-modal.blade.php @@ -0,0 +1,36 @@ +
+ @if ($this->tokenId) + + @slot('title') @lang('pages.user-settings.teams.leave_title') @endslot + + @slot('description') +
+
+ +
+ + +
+ @endslot + + @slot('buttons') +
+ + +
+ @endslot +
+ @endif +
+ diff --git a/resources/views/livewire/logo-upload.blade.php b/resources/views/livewire/logo-upload.blade.php new file mode 100644 index 0000000..b5c52b7 --- /dev/null +++ b/resources/views/livewire/logo-upload.blade.php @@ -0,0 +1,23 @@ +