diff --git a/.devcontainer/.vscode/launch.json b/.devcontainer/.vscode/launch.json new file mode 100644 index 000000000..f855a76bd --- /dev/null +++ b/.devcontainer/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9003 + }, + ] +} diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..97448ed0a --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +FROM php:8.3-apache-bookworm + +# Install PHP extensions +ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ + +RUN install-php-extensions @composer gd intl zip xdebug + +# Enable Apache2 rewrite module +RUN a2enmod rewrite diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 000000000..fa6a74100 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,70 @@ +# Welcome to the Winter development environment + +
+ +
+ +This development environment container sets up a fully-functional installation of Winter CMS, running on Apache 2 with PHP 8.3, and makes it simple to start working with Winter CMS in VSCode, PHPStorm and online code-editing suites such as GitHub Codespaces. + +If you opted to use the `bootstrap-winter` feature, which is enabled by default, Winter CMS will be automatically configured and an administrator account will be generated with the credentials **admin / admin** for you to quickly sign in. It is recommended once you have done so that you change this password immediately. + +The following plugins and themes will be installed automatically with this feature: + +- Workshop theme (https://github.com/wintercms/wn-workshop-theme) +- Pages plugin (https://github.com/wintercms/wn-pages-plugin) +- Blog plugin (https://github.com/wintercms/wn-blog-plugin) +- Test plugin (https://github.com/wintercms/wn-test-plugin) + +## Using this environment + +When this environment is built, the Apache 2 service is automatically started, with the root folder of the Winter project being used. A preview of the website will be opened immediately - if you do not see this, you can open the **Ports** tab in VSCode to view the URL generated for viewing the project. + +XDebug is enabled by default, and allows you to quickly use step debugging. It will be available in the **Debug** tab of VSCode or similar screen in other IDEs. + +By default, when using the `bootstrap-winter` feature, changes to certain folders and locations will be ignored by Git to keep the change list clean. This includes the `plugins` and `themes` folders, the `config/app.php` file and the `composer.json` file in the root folder. If you wish to use this environment for your own projects, it is recommended that you do not use this feature. Please see the **Using in your own projects** section below for using this environment outside of Winter development. + +## Environment platform + +The following software is installed in this environment. + +- Apache 2.4 +- PHP 8.3 with the following extensions: + - `intl` + - `gd` + - `xdebug` +- Composer +- NodeJS 22 (including `npm`) +- Git + +## Using in your own projects + +You may use this development environment for your own projects, making it a great starting point to hit the ground running with Winter. It is recommended that you *disable* the `bootstrap-winter` feature when using this environment for your own projects. + +You may disable this feature by modifying the `.devcontainer/devcontainer.json` file before running the container and commenting out the feature: + +```json5 + "ghcr.io/devcontainers/features/git:1": {}, + "./local-features/apache-config": "latest", + // Comment the following feature if you wish to bootstrap and configure Winter manually (ie. you wish to use this for your own project) + //"./local-features/bootstrap-winter": "latest" + }, + "overrideFeatureInstallOrder": [ +``` + +If this feature is disabled, you must bootstrap your project manually. This includes: + +- Downloading the Composer dependencies. +- Generating the configuration for the project, either as an `.env` file or in the `config` folder. +- Finally, Running the database migrations. + +You may view the `.devcontainer/local-features/bootstrap-winter/bootstrap.sh` file to see how we bootstrap Winter, and run these commands manually. You will only need to do this once per project container. + +If you wish to mount your own volumes, use your own databases or any other complex usages, please review the [Docker documentation](https://docs.docker.com/) to set this up on the container. + +## Troubleshooting + +### Preview website missing styles / assets on Codespaces + +By default, ports that are forwarded in Codespaces are private by default. While we have tried to fix this automatically in the Winter bootstrap process by making the port public through the GitHub CLI, it unfortunately is not consistently applied. + +If you find that your preview website is missing assets or styling, open the **Ports** tab by opening the Action Palette in Codespaces (`F1`) and using the **View: Toggle Ports** action. Right click on the **Preview Winter installation** port, right click on it and choose **Port Visiblity -> Public**. This should resolve the issue. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..d27806e13 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,67 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/debian +{ + "name": "Winter on PHP 8.3", + "build": { + "dockerfile": "./Dockerfile", + "context": "." + }, + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": "true", + "configureZshAsDefaultShell": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": "true" + }, + "ghcr.io/devcontainers/features/node:1": { + "version": "22" + }, + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {}, + "./local-features/apache-config": "latest", + // Comment the following feature if you wish to bootstrap and configure Winter manually (ie. you wish to use this for your own project) + "./local-features/bootstrap-winter": "latest" + }, + "overrideFeatureInstallOrder": [ + "ghcr.io/devcontainers/features/common-utils" + ], + "containerEnv": { + "DB_CONNECTION": "sqlite", + "DB_DATABASE": "${containerWorkspaceFolder}/storage/database.sqlite" + }, + "postStartCommand": "sudo rm -rf /var/www/html && sudo ln -s ${containerWorkspaceFolder} /var/www/html && service apache2 start", + "forwardPorts": [8080], + "portsAttributes": { + "8080": { + "label": "Preview Winter installation", + "onAutoForward": "openPreview" + }, + "9003": { + "label": "Xdebug", + "onAutoForward": "notify" + } + }, + "customizations": { + "vscode": { + "settings": { + "php.validate.executablePath": "/usr/local/bin/php", + "phpcs.executablePath": "${containerWorkspaceFolder}/vendor/bin/phpcs" + }, + "extensions": [ + "xdebug.php-debug", + "bmewburn.vscode-intelephense-client", + "shevaua.phpcs", + "swordev.phpstan", + "wintercms.winter-cms" + ] + }, + "codespaces": { + "openFiles": [ + ".devcontainer/README.md" + ] + } + }, + "remoteUser": "vscode" +} diff --git a/.devcontainer/local-features/apache-config/devcontainer-feature.json b/.devcontainer/local-features/apache-config/devcontainer-feature.json new file mode 100644 index 000000000..b81a3145d --- /dev/null +++ b/.devcontainer/local-features/apache-config/devcontainer-feature.json @@ -0,0 +1,4 @@ +{ + "id": "apache-config", + "name": "Apache configuration changes" +} diff --git a/.devcontainer/local-features/apache-config/install.sh b/.devcontainer/local-features/apache-config/install.sh new file mode 100644 index 000000000..a0273836a --- /dev/null +++ b/.devcontainer/local-features/apache-config/install.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +USERNAME="vscode" + +set -e + +if [ "$(id -u)" -ne 0 ]; then + echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi + +# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies. +export DEBIAN_FRONTEND=noninteractive + +apt-get update && apt-get -y install --no-install-recommends lynx +usermod -aG www-data ${USERNAME} +echo "Listen 8080" > /etc/apache2/ports.conf +apt-get clean -y && rm -rf /var/lib/apt/lists/* + +echo "Done!" diff --git a/.devcontainer/local-features/bootstrap-winter/bootstrap.sh b/.devcontainer/local-features/bootstrap-winter/bootstrap.sh new file mode 100644 index 000000000..c40a2ba33 --- /dev/null +++ b/.devcontainer/local-features/bootstrap-winter/bootstrap.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +set -e + +echo "### Updating Composer dependencies" +php ${PWD}/.devcontainer/local-features/bootstrap-winter/update-composer.php +composer update --no-interaction --no-scripts --no-audit + +if [ ! -f "${PWD}/.env" ]; then + echo "### Generating .env file" + php artisan winter:env -q + php artisan key:generate -q +fi + +if [ "${DB_CONNECTION}" = "sqlite" ] && [ "${DB_DATABASE}" = "${PWD}/storage/database.sqlite" ] && [ ! -f "${PWD}/storage/database.sqlite" ]; then + SETUP_ADMIN=true + echo "### Creating SQLite database" + touch storage/database.sqlite +fi + +echo "### Run migrations" +php artisan migrate + +if [ "${SETUP_ADMIN}" = true ]; then + echo "### Setup admin" + php artisan winter:passwd admin admin +fi + +echo "### Switch theme" +php artisan theme:use workshop + +echo "### Ignoring files in Git" +echo "plugins/*" >> "${PWD}/.git/info/exclude" +echo "themes/*" >> "${PWD}/.git/info/exclude" +echo "composer.json" >> "${PWD}/.git/info/exclude" +git update-index --assume-unchanged composer.json +git restore config + +cp ${PWD}/.devcontainer/.vscode/launch.json ${PWD}/.vscode/launch.json + +if [ "${CODESPACES}" = "true" ]; then + echo "### Configure for Codespaces" + php ${PWD}/.devcontainer/local-features/bootstrap-winter/codespaces.php + git update-index --assume-unchanged config/app.php + gh codespace ports visibility 8080:public -c $CODESPACE_NAME +fi diff --git a/.devcontainer/local-features/bootstrap-winter/codespaces.php b/.devcontainer/local-features/bootstrap-winter/codespaces.php new file mode 100644 index 000000000..2c7ea5604 --- /dev/null +++ b/.devcontainer/local-features/bootstrap-winter/codespaces.php @@ -0,0 +1,25 @@ +set('trustedHosts', [ + 'localhost', + '^(.+\.)?app.github.dev', +]); +$config->set('trustedProxies', '*'); + +$config->write(); + +$env = EnvFile::open($root . '/.env'); + +$env->set('APP_URL', 'https://' . $_ENV['CODESPACE_NAME'] . '.app.github.dev'); +$env->set('LINK_POLICY', 'force'); + +$env->write(); diff --git a/.devcontainer/local-features/bootstrap-winter/devcontainer-feature.json b/.devcontainer/local-features/bootstrap-winter/devcontainer-feature.json new file mode 100644 index 000000000..a9d74f2a9 --- /dev/null +++ b/.devcontainer/local-features/bootstrap-winter/devcontainer-feature.json @@ -0,0 +1,6 @@ +{ + "id": "bootstrap-winter", + "name": "Bootstrap Winter", + "description": "Bootstrap and configure Winter CMS automatically for development on Winter itself", + "postCreateCommand": "sh ./.devcontainer/local-features/bootstrap-winter/bootstrap.sh" +} diff --git a/.devcontainer/local-features/bootstrap-winter/install.sh b/.devcontainer/local-features/bootstrap-winter/install.sh new file mode 100644 index 000000000..4c1268410 --- /dev/null +++ b/.devcontainer/local-features/bootstrap-winter/install.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +echo "Done" diff --git a/.devcontainer/local-features/bootstrap-winter/update-composer.php b/.devcontainer/local-features/bootstrap-winter/update-composer.php new file mode 100644 index 000000000..102ff8abe --- /dev/null +++ b/.devcontainer/local-features/bootstrap-winter/update-composer.php @@ -0,0 +1,22 @@ + 'dev-main', + 'winter/wn-blog-plugin' => 'dev-main', + 'winter/wn-blog-plugin' => 'dev-main', + 'winter/wn-workshop-theme' => 'dev-main', +]; + +// Install Winter packages +foreach ($packages as $package => $version) { + if (!in_array($package, array_keys($composer['require']))) { + $composer['require'][$package] = $version; + } +} + +file_put_contents( + $composerPath, + json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) +); diff --git a/.editorconfig b/.editorconfig index afb383273..39f90e53e 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ insert_final_newline = true indent_style = space indent_size = 4 -[.github/workflows/**.{yml,yaml}] +[**/.github/workflows/**.{yml,yaml}] indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 0c3b228c5..1a7fadf6c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,8 +3,8 @@ *.md diff=markdown *.php diff=php +/.devcontainer export-ignore /.github export-ignore -/.gitpod export-ignore .gitattributes export-ignore -.gitpod.yml export-ignore CHANGELOG.md export-ignore +/package.json export-ignore diff --git a/.github/assets/sponsor-route4me.png b/.github/assets/sponsor-route4me.png new file mode 100644 index 000000000..58e0caffd Binary files /dev/null and b/.github/assets/sponsor-route4me.png differ diff --git a/.github/workflows/archive.yml b/.github/workflows/archive.yml deleted file mode 100644 index 8d2b7ce48..000000000 --- a/.github/workflows/archive.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Archive - -on: - schedule: - - cron: "0 0 * * *" - -jobs: - archive: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v1.1.0 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-stale: 182 - days-before-close: 3 - stale-issue-message: > - This issue will be closed and archived in 3 days, as there has been no activity in this issue for the last 6 months. - - If this issue is still relevant or you would like to see it actioned, please respond within 3 days. - - If this issue is critical for your business, please reach out to us at wintercms@luketowers.ca. - stale-pr-message: > - This pull request will be closed and archived in 3 days, as there has been no activity in this pull request for the last 6 months. - - If you intend to continue working on this pull request, please respond within 3 days. - - If this pull request is critical for your business, please reach out to us at wintercms@luketowers.ca. - stale-issue-label: 'Status: Archived' - stale-pr-label: 'Status: Archived' - exempt-issue-label: 'Status: In Progress' - exempt-pr-label: 'Status: In Progress' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6dd83f406..e14444a88 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -96,7 +96,7 @@ jobs: max-parallel: 8 matrix: operatingSystem: [ubuntu-latest, windows-latest] - phpVersion: ['8.0', '8.1', '8.2'] + phpVersion: ['8.0', '8.1', '8.2', '8.3'] fail-fast: false runs-on: ${{ matrix.operatingSystem }} name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} diff --git a/.gitignore b/.gitignore index 3582897e8..9485e1fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ sftp-config.json nbproject .idea .vscode +!.devcontainer/.vscode _ide_helper.php # Other ignores diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index 8bd98780c..000000000 --- a/.gitpod.yml +++ /dev/null @@ -1,36 +0,0 @@ -image: - file: ./.gitpod/Dockerfile - -tasks: - - init: ./.gitpod/gitpod-init - command: ./.gitpod/gitpod-cmd - -ports: - - port: 1025 - onOpen: ignore - - port: 3306 - onOpen: ignore - - port: 33060 - onOpen: ignore - - port: 8000 - visibility: public - onOpen: ignore - - port: 8025 - onOpen: ignore - - port: 9003 - onOpen: ignore - -vscode: - extensions: - - felixfbecker.php-debug - - bmewburn.vscode-intelephense-client - -github: - prebuilds: - master: false - branches: false - pullRequests: false - pullRequestsFromForks: false - addCheck: false - addComment: false - addBadge: true diff --git a/.gitpod/Dockerfile b/.gitpod/Dockerfile deleted file mode 100644 index 50d7443ee..000000000 --- a/.gitpod/Dockerfile +++ /dev/null @@ -1,71 +0,0 @@ -FROM gitpod/workspace-mysql - -# Install XDebug extension -RUN sudo apt-get update -q \ - && sudo apt-get install -y \ - php-dev \ - golang-go \ - && sudo pecl install xdebug - -# Install Composer 2 (Gitpod comes pre-installed with Composer 1) - borrowed from official Composer Docker image -ENV COMPOSER_ALLOW_SUPERUSER 1 -ENV COMPOSER_HOME /tmp -ENV COMPOSER_VERSION 2.1.6 - -RUN set -eux; \ - curl \ - --silent \ - --fail \ - --location \ - --retry 3 \ - --output /tmp/keys.dev.pub \ - --url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/snapshots.pub \ - ; \ - php -r " \ - \$signature = '4ac45767e5ec22652f0c1167cbbb8a2b0c708369153e328cad90147dafe50952'; \ - \$hash = hash('sha256', preg_replace('{\s}', '', file_get_contents('/tmp/keys.dev.pub'))); \ - if (!hash_equals(\$signature, \$hash)) { \ - echo 'Integrity check failed, dev public key is either corrupt or worse.' . PHP_EOL; \ - exit(1); \ - }" \ - ; \ - curl \ - --silent \ - --fail \ - --location \ - --retry 3 \ - --output /tmp/keys.tags.pub \ - --url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/releases.pub \ - ; \ - php -r " \ - \$signature = '57815ba27e54dc317ecc7cc5573090d087719ba68f3bb7234e5d42d084a14642'; \ - \$hash = hash('sha256', preg_replace('{\s}', '', file_get_contents('/tmp/keys.tags.pub'))); \ - if (!hash_equals(\$signature, \$hash)) { \ - echo 'Integrity check failed, tags public key is either corrupt or worse.' . PHP_EOL; \ - exit(1); \ - }" \ - ; \ - curl \ - --silent \ - --fail \ - --location \ - --retry 3 \ - --output /tmp/installer.php \ - --url https://raw.githubusercontent.com/composer/getcomposer.org/f24b8f860b95b52167f91bbd3e3a7bcafe043038/web/installer \ - ; \ - php -r " \ - \$signature = '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3'; \ - \$hash = hash('sha384', file_get_contents('/tmp/installer.php')); \ - if (!hash_equals(\$signature, \$hash)) { \ - echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; \ - exit(1); \ - }" \ - ; \ - sudo php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION}; \ - composer --ansi --version --no-interaction; \ - composer diagnose; \ - rm -f /tmp/installer.php; \ - sudo find /tmp -type d -exec chmod -v 1777 {} + - -# Configure Xdebug -RUN sudo bash -c "echo -e '\nzend_extension = /usr/lib/php/20190902/xdebug.so\n\n[XDebug]\nxdebug.mode=debug\nxdebug.start_with_request = 1\nxdebug.client_host = 127.0.0.1\n' >> /etc/php/7.4/cli/php.ini" \ No newline at end of file diff --git a/.gitpod/README.md b/.gitpod/README.md deleted file mode 100644 index 183ca41dd..000000000 --- a/.gitpod/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Winter CMS on Gitpod - -Winter CMS now supports the [Gitpod.io](https://gitpod.io) service to provide near-instant development and testing environments for Winter CMS. - -This service allows you to check out the Winter CMS codebase at any commit, any branch or any pull request and be given a full Visual Studio Code environment that is completely configured and bootstrapped to run Winter CMS immediately. - -Each instance contains the following: - -- Winter CMS with the [DebugBar plugin](https://github.com/wintercms/wn-debugbar-plugin). -- VSCode. -- MySQL 5.7. -- PHP 7.4 with all required extensions. -- PHP Xdebug extension. -- Composer 2. -- [MailHog service](https://github.com/mailhog/MailHog/) for capturing emails. - -To use this service, you will need an account on Gitpod - one can easily be created by using your GitHub login. You will receive 50 hours per month free for use on Gitpod, but can opt to increase your hours (or even get unlimited hours) by [purchasing a higher plan](https://www.gitpod.io/pricing) on Gitpod. - -## Creating a Gitpod instance - -There are several ways to create a Gitpod instance of Winter CMS: - -- Use one of the **Open in Gitpod** button, which will be available in the README of Winter CMS, as well as any pull request submitted to Winter CMS. -- Install the [Gitpod extension](https://www.gitpod.io/docs/browser-extension#browser-extension) for Chrome or Firefox, which provides a **Gitpod** button in GitHub. -- Manually create an instance by copying a GitHub address within the Winter CMS repo, and prefixing the address with `https://gitpod.io/#/` - -The Gitpod instance may take a minute or two to boot up if it has not been pre-built. - -> **Note:** For brevity, Gitpod instances have the initial admin account set to **admin / admin** as the username and password to login. If you intend to share the URL, we recommend you change this password. - -## Accessing the services - -The Gitpod instance is set-up to boot all necessary services and then provides two web-facing services - the Winter CMS install itself, which is run on port 8000, and MailHog, which is run on port 8025. - -You can click the **Ports** section in the status bar of VSCode, which will take you to the available ports, and click on one of these ports to view the actions for the port. The "globe" icon will open up a special URL which will access the service on that port. We automatically load up Winter CMS on boot in a new tab. - -### MySQL - -By default, MySQL only runs locally within the Gitpod instance, and cannot be connected to from the outside. However, you can use the [Gitpod Local Companion](https://www.gitpod.io/blog/local-app) service to tunnel into the running Gitpod instance and access its services on your own computer. - -Install the app for your OS, then run `gitpod-local-companion-[darwin|linux|windows]` to set up the tunneling service. For MySQL, this will make the database available on port 3306 on your computer. - -You can then connect to it using any MySQL management program of your choice. - -## Config files - -By default, the Winter CMS Gitpod instance will use `php artisan winter:env` to create an `.env` file that will contain your config. Because this command rewrites the main config files in the `config` directory, which will appear as changes in Git, we mark these files as "unwatched" in Git so that they are not committed to GitHub. - -If you are editing a pull request that does contain config changes that you wish to include in the PR, you can use the `.gitpod/gitpod-show-config` helper script inside your Gitpod instance to make these files appear in the Git changes. - -## Debugging - -Debugging Winter CMS in Gitpod is super simple - all necessary setup has already been done! You can access the Debugging tab in VSCode and press start on the debugging tool to use breakpoints within your code. Note that Gitpod does impose a time limit on responses from the web server, so you may find that using the debugging will result in timeouts when viewing your Winter CMS instance, however, debugging should still continue without issue. diff --git a/.gitpod/gitpod-cmd b/.gitpod/gitpod-cmd deleted file mode 100755 index fd285b6e8..000000000 --- a/.gitpod/gitpod-cmd +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# Create database -gp await-port 3306 && mysql -e "DROP DATABASE IF EXISTS winter" -mysql -e "CREATE DATABASE winter" - -# Create environment file -php artisan winter:env - -# Hide config file changes from Git -./.gitpod/gitpod-hide-config - -# Exclude Debugbar files from Git -echo -e "plugins/winter/debugbar\nstorage/debugbar" >> ./.git/info/exclude - -# Rewrite configuration -sed -i "s|APP_URL=.*$|APP_URL=${GITPOD_WORKSPACE_URL}|g" .env -sed -i "s|APP_URL=https://|APP_URL=https://8000-|g" .env -sed -i "s|APP_KEY=.*$|APP_KEY=$(cat /dev/urandom | base64 | head -c 32)|g" .env -sed -i "s|DB_CONNECTION=.*$|DB_CONNECTION=mysql|g" .env -sed -i "s|DB_HOST=.*$|DB_HOST=127.0.0.1|g" .env -sed -i "s|DB_PORT=.*$|DB_PORT=3306|g" .env -sed -i "s|DB_DATABASE=.*$|DB_DATABASE=winter|g" .env -sed -i "s|DB_USERNAME=.*$|DB_USERNAME=root|g" .env -sed -i "s|DB_PASSWORD=.*$|DB_PASSWORD=|g" .env -sed -i "s|MAIL_DRIVER=.*$|MAIL_DRIVER=smtp|g" .env -sed -i "s|MAIL_HOST=.*$|MAIL_HOST=127.0.0.1|g" .env -sed -i "s|MAIL_PORT=.*$|MAIL_PORT=1025|g" .env -sed -i "s|MAIL_ENCRYPTION=.*$|MAIL_ENCRYPTION=null|g" .env -sed -i "s|MAIL_USERNAME=.*$|MAIL_USERNAME=null|g" .env -sed -i "s|MAIL_PASSWORD=.*$|MAIL_PASSWORD=null|g" .env -sed -i "s|'trustedProxies' => null|'trustedProxies' => '*'|g" config/app.php - -# Run migrations -php artisan winter:up - -# Set admin password -php artisan winter:passwd admin admin - -# Run Mailhog in background -/workspace/go/bin/MailHog >/dev/null 2>&1 & - -# Serve site -php artisan serve >/dev/null 2>&1 & -gp await-port 8000 && gp preview --external $(gp url 8000) - -# Open README -gp open ./.gitpod/README.md diff --git a/.gitpod/gitpod-hide-config b/.gitpod/gitpod-hide-config deleted file mode 100755 index 149a84f8a..000000000 --- a/.gitpod/gitpod-hide-config +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# Hide config file edits from Git changes -git update-index --skip-worktree config/app.php -git update-index --skip-worktree config/cache.php -git update-index --skip-worktree config/cms.php -git update-index --skip-worktree config/database.php -git update-index --skip-worktree config/mail.php -git update-index --skip-worktree config/queue.php -git update-index --skip-worktree config/session.php -git update-index --skip-worktree package.json diff --git a/.gitpod/gitpod-init b/.gitpod/gitpod-init deleted file mode 100755 index 086705c79..000000000 --- a/.gitpod/gitpod-init +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Install Mailhog -go get github.com/mailhog/MailHog - -# Add Debug Bar plugin -composer require --no-update "winter/wn-debugbar-plugin" "4.0.0" - -# Install Composer dependencies -composer update --no-progress -git reset --hard - -# Setup VSCode config -mkdir -p ./.vscode -cp ./.gitpod/vscode-launch.json ./.vscode/launch.json diff --git a/.gitpod/gitpod-show-config b/.gitpod/gitpod-show-config deleted file mode 100755 index d21820e87..000000000 --- a/.gitpod/gitpod-show-config +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# Hide config file edits from Git changes -git update-index --no-skip-worktree config/app.php -git update-index --no-skip-worktree config/cache.php -git update-index --no-skip-worktree config/cms.php -git update-index --no-skip-worktree config/database.php -git update-index --no-skip-worktree config/mail.php -git update-index --no-skip-worktree config/queue.php -git update-index --no-skip-worktree config/session.php -git update-index --no-skip-worktree package.json diff --git a/.gitpod/vscode-launch.json b/.gitpod/vscode-launch.json deleted file mode 100644 index 542060d33..000000000 --- a/.gitpod/vscode-launch.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Listen for Xdebug", - "type": "php", - "request": "launch", - "port": 9003 - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 502b72964..4f0c15ea9 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,7 @@ No matter how large or small your project is, Winter provides a rich development [![Version](https://img.shields.io/github/v/release/wintercms/winter?sort=semver&style=flat-square)](https://github.com/wintercms/winter/releases) [![Tests](https://img.shields.io/github/actions/workflow/status/wintercms/winter/tests.yml?branch=develop&label=tests&style=flat-square)](https://github.com/wintercms/winter/actions) [![License](https://img.shields.io/github/license/wintercms/winter?label=open%20source&style=flat-square)](https://packagist.org/packages/wintercms/winter) -[![Discord](https://img.shields.io/discord/816852513684193281?label=discord&style=flat-square)](https://discord.gg/D5MFSPH6Ux) -[![RINGER](https://www.ringerhq.com/images/get-support-on-ringer.svg)](https://www.ringerhq.com/i/wintercms/winter) - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/wintercms/winter) +[![Discord](https://img.shields.io/badge/discord-join-purple?style=flat-square&logo=discord&logoColor=white)](https://discord.gg/D5MFSPH6Ux) ## Installing Winter @@ -90,6 +87,10 @@ Winter CMS development is financially supported by the generosity of the followi ### Organizations +[![Route4Me logo, Route Planning and Route Mapping](https://raw.githubusercontent.com/wintercms/winter/develop/.github/assets/sponsor-route4me.png)](https://route4me.com/?utm_source=wintercms) + +Route4Me is a [Premium Sponsor to the Winter CMS Open Collective](https://opencollective.com/wintercms). + [![Froala logo](https://froala.com/wp-content/uploads/2019/10/froala.svg)](https://froala.com/wysiwyg-editor/) Froala provides a perpetual, Enterprise license to Winter CMS which allows us and our users to use the Froala WYSIWYG Editor in Winter CMS powered projects. diff --git a/composer.json b/composer.json index 7c6a2dd16..3bb371bc2 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ ], "support": { "issues": "https://github.com/wintercms/winter/issues", - "docs": "https://wintercms.github.io/docs/", + "docs": "https://wintercms.com/docs/", "discord": "https://discord.gg/D5MFSPH6Ux", "source": "https://github.com/wintercms/winter" }, @@ -47,7 +47,9 @@ }, "scripts": { "post-create-project-cmd": [ - "@php artisan key:generate" + "@php artisan winter:install", + "@php artisan winter:env", + "@php artisan winter:mirror public --relative" ], "post-update-cmd": [ "@php artisan winter:version", diff --git a/config/app.php b/config/app.php index 1520e862c..b740d465e 100644 --- a/config/app.php +++ b/config/app.php @@ -14,6 +14,10 @@ | You can create a CMS page with route "/error" to set the contents | of this page. Otherwise a default error page is shown. | + | IMPORTANT: Always have debug mode set to false in production environments + | as it can reveal sensitive information about your application and + | infrastructure to untrusted users through more detailed errors. + | */ 'debug' => env('APP_DEBUG', true), diff --git a/modules/backend/ServiceProvider.php b/modules/backend/ServiceProvider.php index d300988aa..8d352d294 100644 --- a/modules/backend/ServiceProvider.php +++ b/modules/backend/ServiceProvider.php @@ -1,13 +1,19 @@ registerMailer(); $this->registerAssetBundles(); $this->registerBackendPermissions(); + $this->registerBackendUserEvents(); /* * Backend specific @@ -55,7 +62,7 @@ protected function registerConsole() $this->registerConsoleCommand('create.controller', \Backend\Console\CreateController::class); $this->registerConsoleCommand('create.formwidget', \Backend\Console\CreateFormWidget::class); $this->registerConsoleCommand('create.reportwidget', \Backend\Console\CreateReportWidget::class); - + $this->registerConsoleCommand('user.create', \Backend\Console\UserCreate::class); $this->registerConsoleCommand('winter.passwd', \Backend\Console\WinterPasswd::class); } @@ -207,6 +214,28 @@ protected function registerBackendPermissions() }); } + /** + * Register the backend user events + */ + protected function registerBackendUserEvents() + { + Event::listen('backend.user.login', function (\Backend\Models\User $user) { + // @TODO: Deprecate this, and only run migrations when it makes sense + $runMigrationsOnLogin = (bool) Config::get('cms.runMigrationsOnLogin', Config::get('app.debug', false)); + if ($runMigrationsOnLogin) { + try { + // Load version updates + UpdateManager::instance()->update(); + } catch (Exception $e) { + Flash::error($e->getMessage()); + } + } + + // Log the sign in event + AccessLog::add($user); + }); + } + /* * Register widgets */ diff --git a/modules/backend/assets/css/winter.css b/modules/backend/assets/css/winter.css index ed82c286b..765423d07 100644 --- a/modules/backend/assets/css/winter.css +++ b/modules/backend/assets/css/winter.css @@ -304,7 +304,7 @@ html.mobile .control-scrollbar{overflow:auto;-webkit-overflow-scrolling:touch} .control-treeview ol>li>div{font-size:14px;font-weight:normal;background:#fff;border-bottom:1px solid #ecf0f1;position:relative} .control-treeview ol>li>div>a{color:#2b3e50;padding:11px 45px 10px 61px;display:block;line-height:150%;text-decoration:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .control-treeview ol>li>div:before{content:' ';background-image:url(../images/treeview-icons.png);background-position:0 -28px;background-repeat:no-repeat;background-size:42px auto;position:absolute;width:21px;height:22px;left:28px;top:15px} -.control-treeview ol>li>div span.comment{display:block;font-weight:400;color:#95a5a6;font-size:13px;margin-top:2px;overflow:hidden;text-overflow:ellipsis} +.control-treeview ol>li>div span.comment{display:block;font-weight:400;color:#95a5a6;font-size:13px;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .control-treeview ol>li>div>span.expand{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;display:none;position:absolute;width:20px;height:20px;top:19px;left:2px;cursor:pointer;color:#bdc3c7;-webkit-transition:transform 0.1s ease;transition:transform 0.1s ease} .control-treeview ol>li>div>span.expand:before{font-family:"Font Awesome 6 Free";font-weight:900;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-style:normal;font-variant:normal;text-rendering:auto;content:"\f0da";line-height:100%;font-size:15px;position:relative;left:8px;top:2px} .control-treeview ol>li>div>span.drag-handle{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;-webkit-transition:opacity 0.4s;transition:opacity 0.4s;position:absolute;right:9px;bottom:0;width:18px;height:19px;cursor:move;color:#bdc3c7;opacity:0;filter:alpha(opacity=0)} @@ -358,8 +358,10 @@ html.mobile .control-scrollbar{overflow:auto;-webkit-overflow-scrolling:touch} .control-treeview ol>li.has-subitems>div.popover-highlight:before{background-position:0 -52px} .control-treeview ol>li.has-subitems>div span.expand{display:block} .control-treeview ol>li.placeholder{position:relative;opacity:0.5;filter:alpha(opacity=50)} +.control-treeview ol>li.placeholder ol{display:none} .control-treeview ol>li.dragged{position:absolute;z-index:2000;opacity:0.25;filter:alpha(opacity=25)} .control-treeview ol>li.dragged>div{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} +.control-treeview ol>li.dragged ol{display:none} .control-treeview ol>li.drop-target>div{background-color:#2581b8 !important} .control-treeview ol>li.drop-target>div>a{color:#fff} .control-treeview ol>li.drop-target>div>a>span.comment{color:#fff} @@ -438,7 +440,7 @@ html.mobile .control-scrollbar{overflow:auto;-webkit-overflow-scrolling:touch} .control-treeview.treeview-light ol>li>div>ul.submenu li p a{display:table-cell;vertical-align:middle;height:100%;padding:0 20px;font-size:13px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .control-treeview.treeview-light ol>li>div>ul.submenu li p a i.control-icon{font-size:22px;margin-right:0} body.dragging .control-treeview ol.dragging, -body.dragging .control-treeview ol.dragging ol{background:#ccc;padding-right:20px;-webkit-transition:padding 1s;transition:padding 1s} +body.dragging .control-treeview ol.dragging ol{background:#ccc;padding-right:0} body.dragging .control-treeview ol.dragging>li>div, body.dragging .control-treeview ol.dragging ol>li>div{margin-right:0;-webkit-transition:margin 1s;transition:margin 1s} body.dragging .control-treeview ol.dragging>li>div .custom-checkbox, @@ -1101,4 +1103,4 @@ html.cssanimations .fancy-layout *:not(.nested-form)>.form-widget>.layout-row>.f .flyout-toggle i{margin:7px 0 0 6px;display:inline-block} .flyout-toggle:hover i{color:#fff} body.flyout-visible{overflow:hidden} -body.flyout-visible .flyout-overlay{background-color:rgba(0,0,0,0.3)} \ No newline at end of file +body.flyout-visible .flyout-overlay{background-color:rgba(0,0,0,0.3)} diff --git a/modules/backend/assets/less/controls/treeview.less b/modules/backend/assets/less/controls/treeview.less index 3b2b24b8a..c9da29a73 100644 --- a/modules/backend/assets/less/controls/treeview.less +++ b/modules/backend/assets/less/controls/treeview.less @@ -57,6 +57,7 @@ margin-top: 2px; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } > span.expand { @@ -297,6 +298,10 @@ &.placeholder { position: relative; .opacity(.5); + + ol { + display: none; + } } &.dragged { @@ -307,6 +312,10 @@ > div { .border-radius(3px); } + + ol { + display: none; + } } &.drop-target { @@ -548,8 +557,7 @@ body.dragging .control-treeview { ol.dragging, ol.dragging ol { background: #ccc; - padding-right: 20px; - .transition(padding 1s); + padding-right: 0; > li { > div { diff --git a/modules/backend/assets/ui/js/build/backend.js b/modules/backend/assets/ui/js/build/backend.js index 133d5e72d..251900720 100644 --- a/modules/backend/assets/ui/js/build/backend.js +++ b/modules/backend/assets/ui/js/build/backend.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_backend_module=self.webpackChunk_wintercms_wn_backend_module||[]).push([[147],{613:function(e,t,n){var i=n(471),r=n(341);class s extends Snowboard.Singleton{listens(){return{ready:"ready",ajaxFetchOptions:"ajaxFetchOptions",ajaxUpdateComplete:"ajaxUpdateComplete"}}ready(){window.jQuery&&((0,r.c)("render"),document.addEventListener("$render",(()=>{this.snowboard.globalEvent("render")})),window.jQuery(document).trigger("render"))}addPrefilter(){window.jQuery&&window.jQuery.ajaxPrefilter((e=>{this.hasToken()&&(e.headers||(e.headers={}),e.headers["X-CSRF-TOKEN"]=this.getToken())}))}ajaxFetchOptions(e){this.hasToken()&&(e.headers["X-CSRF-TOKEN"]=this.getToken())}ajaxUpdateComplete(){window.jQuery&&window.jQuery(document).trigger("render")}hasToken(){const e=document.querySelector('meta[name="csrf-token"]');return!!e&&!!e.hasAttribute("content")}getToken(){return document.querySelector('meta[name="csrf-token"]').getAttribute("content")}}class a extends Snowboard.PluginBase{construct(e,t){if(e instanceof Snowboard.PluginBase==!1)throw new Error("Event handling can only be applied to Snowboard classes.");if(!t)throw new Error("Event prefix is required.");this.instance=e,this.eventPrefix=t,this.events=[]}on(e,t){this.events.push({event:e,callback:t})}off(e,t){this.events=this.events.filter((n=>n.event!==e||n.callback!==t))}once(e,t){var n=this;const i=this.events.push({event:e,callback:function(){t(...arguments),n.events.splice(i-1,1)}})}fire(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i{const{slotScopeIds:a}=t;a&&(o=o?o.concat(a):a);const f=i(e),d=p(s(e),t,f,n,r,o,c);return d&&Jr(d)&&"]"===d.data?s(t.anchor=d):(zr(),l(t.anchor=u("]"),f,d),d)},m=(e,t,r,o,l,a)=>{if(no(e.parentElement,1)||(__VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&On("Hydration node mismatch:\n- rendered on server:",e,3===e.nodeType?"(text)":Jr(e)&&"["===e.data?"(start of fragment)":"","\n- expected on client:",t.type),zr()),t.el=null,a){const t=g(e);for(;;){const n=s(e);if(!n||n===t)break;c(n)}}const u=s(e),f=i(e);return c(e),n(null,t,f,u,r,o,Kr(f),l),u},g=(e,t="[",n="]")=>{let r=0;for(;e;)if((e=s(e))&&Jr(e)&&(e.data===t&&r++,e.data===n)){if(0===r)return s(e);r--}return e},v=(e,t,n)=>{const r=t.parentNode;r&&r.replaceChild(e,t);let o=n;for(;o;)o.vnode.el===t&&(o.vnode.el=o.subTree.el=e),o=o.parent},y=e=>1===e.nodeType&&"TEMPLATE"===e.tagName;return[(e,t)=>{if(!t.hasChildNodes())return __VUE_PROD_HYDRATION_MISMATCH_DETAILS__&&On("Attempting to hydrate existing markup but container is empty. Performing full mount instead."),n(null,e,t),tr(),void(t._vnode=e);f(t.firstChild,e,null,null,null),tr(),t._vnode=e},f]}function Gr(e,t,n,r,o){let s,i,c,l;if("class"===t)c=e.getAttribute("class"),l=X(n),function(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}(Xr(c||""),Xr(l))||(s=2,i="class");else if("style"===t){c=e.getAttribute("style")||"",l=_(n)?n:function(e){let t="";if(!e||_(e))return t;for(const n in e){const r=e[n];(_(r)||"number"==typeof r)&&(t+=`${n.startsWith("--")?n:D(n)}:${r};`)}return t}(z(n));const t=Qr(c),a=Qr(l);if(r.dirs)for(const{dir:e,value:t}of r.dirs)"show"!==e.name||t||a.set("display","none");o&&Zr(o,r,a),function(e,t){if(e.size!==t.size)return!1;for(const[n,r]of e)if(r!==t.get(n))return!1;return!0}(t,a)||(s=3,i="style")}else(e instanceof SVGElement&&le(t)||e instanceof HTMLElement&&(se(t)||ce(t)))&&(se(t)?(c=e.hasAttribute(t),l=ie(n)):null==n?(c=e.hasAttribute(t),l=!1):(c=e.hasAttribute(t)?e.getAttribute(t):"value"===t&&"TEXTAREA"===e.tagName&&e.value,l=!!function(e){if(null==e)return!1;const t=typeof e;return"string"===t||"number"===t||"boolean"===t}(n)&&String(n)),c!==l&&(s=4,i=t));if(null!=s&&!no(e,s)){const t=e=>!1===e?"(not rendered)":`${i}="${e}"`;return On(`Hydration ${to[s]} mismatch on`,e,`\n - rendered on server: ${t(c)}\n - expected on client: ${t(l)}\n Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead.\n You should fix the source of the mismatch.`),!0}return!1}function Xr(e){return new Set(e.trim().split(/\s+/))}function Qr(e){const t=new Map;for(const n of e.split(";")){let[e,r]=n.split(":");e=e.trim(),r=r&&r.trim(),e&&r&&t.set(e,r)}return t}function Zr(e,t,n){const r=e.subTree;if(e.getCssVars&&(t===r||r&&r.type===Ii&&r.children.includes(t))){const t=e.getCssVars();for(const e in t)n.set(`--${ue(e,!1)}`,String(t[e]))}t===r&&e.parent&&Zr(e.parent,e.vnode,n)}const eo="data-allow-mismatch",to={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function no(e,t){if(0===t||1===t)for(;e&&!e.hasAttribute(eo);)e=e.parentElement;const n=e&&e.getAttribute(eo);if(null==n)return!1;if(""===n)return!0;{const e=n.split(",");return!(0!==t||!e.includes("children"))||n.split(",").includes(to[t])}}const ro=(e=1e4)=>t=>{const n=requestIdleCallback(t,{timeout:e});return()=>cancelIdleCallback(n)};const oo=e=>(t,n)=>{const r=new IntersectionObserver((e=>{for(const n of e)if(n.isIntersecting){r.disconnect(),t();break}}),e);return n((e=>{if(e instanceof Element)return function(e){const{top:t,left:n,bottom:r,right:o}=e.getBoundingClientRect(),{innerHeight:s,innerWidth:i}=window;return(t>0&&t c))for(const s of v){const c=d[(o?"v":"h")+s];if(!(c = e($file->sizeToString()) ?>0&&r0&&n0&&or.disconnect()},so=e=>t=>{if(e){const n=matchMedia(e);if(!n.matches)return n.addEventListener("change",t,{once:!0}),()=>n.removeEventListener("change",t);t()}},io=(e=[])=>(t,n)=>{_(e)&&(e=[e]);let r=!1;const o=e=>{r||(r=!0,s(),t(),e.target.dispatchEvent(new e.constructor(e.type,e)))},s=()=>{n((t=>{for(const n of e)t.removeEventListener(n,o)}))};return n((t=>{for(const n of e)t.addEventListener(n,o,{once:!0})})),s};const co=e=>!!e.type.__asyncLoader
+/*! #__NO_SIDE_EFFECTS__ */;function lo(e){b(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,hydrate:s,timeout:i,suspensible:c=!0,onError:l}=e;let a,u=null,f=0;const d=()=>{let e;return u||(e=u=t().catch((e=>{if(e=e instanceof Error?e:new Error(String(e)),l)return new Promise(((t,n)=>{l(e,(()=>t((f++,u=null,d()))),(()=>n(e)),f+1)}));throw e})).then((t=>e!==u&&u?u:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),a=t,t))))};return Br({name:"AsyncComponentWrapper",__asyncLoader:d,__asyncHydrate(e,t,n){const r=s?()=>{const r=s(n,(t=>function(e,t){if(Jr(e)&&"["===e.data){let n=1,r=e.nextSibling;for(;r;){if(1===r.nodeType){if(!1===t(r))break}else if(Jr(r))if("]"===r.data){if(0==--n)break}else"["===r.data&&n++;r=r.nextSibling}}else t(e)}(e,t)));r&&(t.bum||(t.bum=[])).push(r)}:n;a?r():d().then((()=>!t.isUnmounted&&r()))},get __asyncResolved(){return a},setup(){const e=fc;if(Hr(e),a)return()=>ao(a,e);const t=t=>{u=null,Bn(t,e,13,!r)};if(c&&e.suspense||_c)return d().then((t=>()=>ao(t,e))).catch((e=>(t(e),()=>r?Gi(r,{error:e}):null)));const s=on(!1),l=on(),f=on(!!o);return o&&setTimeout((()=>{f.value=!1}),o),null!=i&&setTimeout((()=>{if(!s.value&&!l.value){const e=new Error(`Async component timed out after ${i}ms.`);t(e),l.value=e}}),i),d().then((()=>{s.value=!0,e.parent&&uo(e.parent.vnode)&&e.parent.update()})).catch((e=>{t(e),l.value=e})),()=>s.value&&a?ao(a,e):l.value&&r?Gi(r,{error:l.value}):n&&!f.value?Gi(n):void 0}})}function ao(e,t){const{ref:n,props:r,children:o,ce:s}=t.vnode,i=Gi(e,r,o);return i.ref=n,i.ce=s,delete t.vnode.ce,i}const uo=e=>e.type.__isKeepAlive,fo={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=dc(),r=n.ctx;if(!r.renderer)return()=>{const e=t.default&&t.default();return e&&1===e.length?e[0]:e};const o=new Map,s=new Set;let i=null;const c=n.suspense,{renderer:{p:l,m:a,um:u,o:{createElement:f}}}=r,d=f("div");function p(e){yo(e),u(e,n,c,!0)}function h(e){o.forEach(((t,n)=>{const r=Rc(t.type);r&&!e(r)&&m(n)}))}function m(e){const t=o.get(e);!t||i&&Wi(t,i)?i&&yo(i):p(t),o.delete(e),s.delete(e)}r.activate=(e,t,n,r,o)=>{const s=e.component;a(e,t,n,0,c),l(s.vnode,e,t,n,s,c,r,e.slotScopeIds,o),zs((()=>{s.isDeactivated=!1,s.a&&V(s.a);const t=e.props&&e.props.onVnodeMounted;t&&cc(t,s.parent,e)}),c)},r.deactivate=e=>{const t=e.component;ti(t.m),ti(t.a),a(e,d,null,1,c),zs((()=>{t.da&&V(t.da);const n=e.props&&e.props.onVnodeUnmounted;n&&cc(n,t.parent,e),t.isDeactivated=!0}),c)},ci((()=>[e.include,e.exclude]),(([e,t])=>{e&&h((t=>po(e,t))),t&&h((e=>!po(t,e)))}),{flush:"post",deep:!0});let g=null;const v=()=>{null!=g&&(xi(n.subTree.type)?zs((()=>{o.set(g,bo(n.subTree))}),n.subTree.suspense):o.set(g,bo(n.subTree)))};return Co(v),To(v),Eo((()=>{o.forEach((e=>{const{subTree:t,suspense:r}=n,o=bo(t);if(e.type!==o.type||e.key!==o.key)p(e);else{yo(o);const e=o.component.da;e&&zs(e,r)}}))})),()=>{if(g=null,!t.default)return i=null;const n=t.default(),r=n[0];if(n.length>1)return i=null,n;if(!(qi(r)&&(4&r.shapeFlag||128&r.shapeFlag)))return i=null,r;let c=bo(r);if(c.type===Oi)return i=null,c;const l=c.type,a=Rc(co(c)?c.type.__asyncResolved||{}:l),{include:u,exclude:f,max:d}=e;if(u&&(!a||!po(u,a))||f&&a&&po(f,a))return c.shapeFlag&=-257,i=c,r;const p=null==c.key?l:c.key,h=o.get(p);return c.el&&(c=Zi(c),128&r.shapeFlag&&(r.ssContent=c)),g=p,h?(c.el=h.el,c.component=h.component,c.transition&&Fr(c,c.transition),c.shapeFlag|=512,s.delete(p),s.add(p)):(s.add(p),d&&s.size>parseInt(d,10)&&m(s.values().next().value)),c.shapeFlag|=256,i=c,xi(r.type)?r:c}}};function po(e,t){return m(e)?e.some((e=>po(e,t))):_(e)?e.split(",").includes(t):"[object RegExp]"===T(e)&&(e.lastIndex=0,e.test(t))}function ho(e,t){go(e,"a",t)}function mo(e,t){go(e,"da",t)}function go(e,t,n=fc){const r=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()});if(_o(t,r,n),n){let e=n.parent;for(;e&&e.parent;)uo(e.parent.vnode)&&vo(r,t,n,e),e=e.parent}}function vo(e,t,n,r){const o=_o(t,e,r,!0);wo((()=>{d(r[t],o)}),n)}function yo(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function bo(e){return 128&e.shapeFlag?e.ssContent:e}function _o(e,t,n=fc,r=!1){if(n){const o=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...r)=>{Be();const o=mc(n),s=Vn(t,n,e,r);return o(),Ue(),s});return r?o.unshift(s):o.push(s),s}}const So=e=>(t,n=fc)=>{_c&&"sp"!==e||_o(e,((...e)=>t(...e)),n)},xo=So("bm"),Co=So("m"),ko=So("bu"),To=So("u"),Eo=So("bum"),wo=So("um"),Ao=So("sp"),No=So("rtg"),Io=So("rtc");function Ro(e,t=fc){_o("ec",e,t)}const Oo="components",Mo="directives";function Po(e,t){return Fo(Oo,e,!0,t)||e}const Do=Symbol.for("v-ndc");function Lo(e){return _(e)?Fo(Oo,e,!1)||e:e||Do}function $o(e){return Fo(Mo,e)}function Fo(e,t,n=!0,r=!1){const o=cr||fc;if(o){const n=o.type;if(e===Oo){const e=Rc(n,!1);if(e&&(e===t||e===M(t)||e===L(M(t))))return n}const s=Vo(o[e]||n[e],t)||Vo(o.appContext[e],t);return!s&&r?n:s}}function Vo(e,t){return e&&(e[t]||e[M(t)]||e[L(M(t))])}function Bo(e,t,n,r){let o;const s=n&&n[r],i=m(e);if(i||_(e)){let n=!1;i&&Yt(e)&&(n=!Xt(e),e=et(e)),o=new Array(e.length);for(let r=0,i=e.length;rt(e,n,void 0,s&&s[n])));else{const n=Object.keys(e);o=new Array(n.length);for(let r=0,i=n.length;r{const t=r.fn(...e);return t&&(t.key=r.key),t}:r.fn)}return e}function Ho(e,t,n={},r,o){if(cr.ce||cr.parent&&co(cr.parent)&&cr.parent.ce)return"default"!==t&&(n.name=t),Li(),ji(Ii,null,[Gi("slot",n,r&&r())],64);let s=e[t];s&&s._c&&(s._d=!1),Li();const i=s&&jo(s(n)),c=ji(Ii,{key:(n.key||i&&i.key||`_${t}`)+(!i&&r?"_fb":"")},i||(r?r():[]),i&&1===e._?64:-2);return!o&&c.scopeId&&(c.slotScopeIds=[c.scopeId+"-s"]),s&&s._c&&(s._d=!0),c}function jo(e){return e.some((e=>!qi(e)||e.type!==Oi&&!(e.type===Ii&&!jo(e.children))))?e:null}function qo(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:$(r)]=e[r];return n}const Wo=e=>e?vc(e)?Ac(e):Wo(e.parent):null,zo=f(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Wo(e.parent),$root:e=>Wo(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>ms(e),$forceUpdate:e=>e.f||(e.f=()=>{Xn(e.update)}),$nextTick:e=>e.n||(e.n=Gn.bind(e.proxy)),$watch:e=>ai.bind(e)}),Ko=(e,t)=>e!==s&&!e.__isScriptSetup&&h(e,t),Jo={get({_:e},t){if("__v_skip"===t)return!0;const{ctx:n,setupState:r,data:o,props:i,accessCache:c,type:l,appContext:a}=e;let u;if("$"!==t[0]){const l=c[t];if(void 0!==l)switch(l){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return i[t]}else{if(Ko(r,t))return c[t]=1,r[t];if(o!==s&&h(o,t))return c[t]=2,o[t];if((u=e.propsOptions[0])&&h(u,t))return c[t]=3,i[t];if(n!==s&&h(n,t))return c[t]=4,n[t];fs&&(c[t]=0)}}const f=zo[t];let d,p;return f?("$attrs"===t&&Xe(e.attrs,0,""),f(e)):(d=l.__cssModules)&&(d=d[t])?d:n!==s&&h(n,t)?(c[t]=4,n[t]):(p=a.config.globalProperties,h(p,t)?p[t]:void 0)},set({_:e},t,n){const{data:r,setupState:o,ctx:i}=e;return Ko(o,t)?(o[t]=n,!0):r!==s&&h(r,t)?(r[t]=n,!0):!h(e.props,t)&&(("$"!==t[0]||!(t.slice(1)in e))&&(i[t]=n,!0))},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:i}},c){let l;return!!n[c]||e!==s&&h(e,c)||Ko(t,c)||(l=i[0])&&h(l,c)||h(r,c)||h(zo,c)||h(o.config.globalProperties,c)},defineProperty(e,t,n){return null!=n.get?e._.accessCache[t]=0:h(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};const Yo=f({},Jo,{get(e,t){if(t!==Symbol.unscopables)return Jo.get(e,t,e)},has(e,t){return"_"!==t[0]&&!W(t)}});function Go(){return null}function Xo(){return null}function Qo(e){0}function Zo(e){0}function es(){return null}function ts(){0}function ns(e,t){return null}function rs(){return ss().slots}function os(){return ss().attrs}function ss(){const e=dc();return e.setupContext||(e.setupContext=wc(e))}function is(e){return m(e)?e.reduce(((e,t)=>(e[t]=null,e)),{}):e}function cs(e,t){const n=is(e);for(const e in t){if(e.startsWith("__skip"))continue;let r=n[e];r?m(r)||b(r)?r=n[e]={type:r,default:t[e]}:r.default=t[e]:null===r&&(r=n[e]={default:t[e]}),r&&t[`__skip_${e}`]&&(r.skipFactory=!0)}return n}function ls(e,t){return e&&t?m(e)&&m(t)?e.concat(t):f({},is(e),is(t)):e||t}function as(e,t){const n={};for(const r in e)t.includes(r)||Object.defineProperty(n,r,{enumerable:!0,get:()=>e[r]});return n}function us(e){const t=dc();let n=e();return gc(),C(n)&&(n=n.catch((e=>{throw mc(t),e}))),[n,()=>mc(t)]}let fs=!0;function ds(e){const t=ms(e),n=e.proxy,r=e.ctx;fs=!1,t.beforeCreate&&ps(t.beforeCreate,e,"bc");const{data:o,computed:s,methods:i,watch:l,provide:a,inject:u,created:f,beforeMount:d,mounted:p,beforeUpdate:h,updated:g,activated:v,deactivated:y,beforeDestroy:_,beforeUnmount:S,destroyed:C,unmounted:k,render:T,renderTracked:E,renderTriggered:w,errorCaptured:A,serverPrefetch:N,expose:I,inheritAttrs:R,components:O,directives:M,filters:P}=t;if(u&&function(e,t){m(e)&&(e=bs(e));for(const n in e){const r=e[n];let o;o=x(r)?"default"in r?As(r.from||n,r.default,!0):As(r.from||n):As(r),rn(o)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>o.value,set:e=>o.value=e}):t[n]=o}}(u,r,null),i)for(const e in i){const t=i[e];b(t)&&(r[e]=t.bind(n))}if(o){0;const t=o.call(n,n);0,x(t)&&(e.data=qt(t))}if(fs=!0,s)for(const e in s){const t=s[e],o=b(t)?t.bind(n,n):b(t.get)?t.get.bind(n,n):c;0;const i=!b(t)&&b(t.set)?t.set.bind(n):c,l=Pc({get:o,set:i});Object.defineProperty(r,e,{enumerable:!0,configurable:!0,get:()=>l.value,set:e=>l.value=e})}if(l)for(const e in l)hs(l[e],r,n,e);if(a){const e=b(a)?a.call(n):a;Reflect.ownKeys(e).forEach((t=>{ws(t,e[t])}))}function D(e,t){m(t)?t.forEach((t=>e(t.bind(n)))):t&&e(t.bind(n))}if(f&&ps(f,e,"c"),D(xo,d),D(Co,p),D(ko,h),D(To,g),D(ho,v),D(mo,y),D(Ro,A),D(Io,E),D(No,w),D(Eo,S),D(wo,k),D(Ao,N),m(I))if(I.length){const t=e.exposed||(e.exposed={});I.forEach((e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t})}))}else e.exposed||(e.exposed={});T&&e.render===c&&(e.render=T),null!=R&&(e.inheritAttrs=R),O&&(e.components=O),M&&(e.directives=M),N&&Hr(e)}function ps(e,t,n){Vn(m(e)?e.map((e=>e.bind(t.proxy))):e.bind(t.proxy),t,n)}function hs(e,t,n,r){let o=r.includes(".")?ui(n,r):()=>n[r];if(_(e)){const n=t[e];b(n)&&ci(o,n)}else if(b(e))ci(o,e.bind(n));else if(x(e))if(m(e))e.forEach((e=>hs(e,t,n,r)));else{const r=b(e.handler)?e.handler.bind(n):t[e.handler];b(r)&&ci(o,r,e)}else 0}function ms(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:s,config:{optionMergeStrategies:i}}=e.appContext,c=s.get(t);let l;return c?l=c:o.length||n||r?(l={},o.length&&o.forEach((e=>gs(l,e,i,!0))),gs(l,t,i)):l=t,x(t)&&s.set(t,l),l}function gs(e,t,n,r=!1){const{mixins:o,extends:s}=t;s&&gs(e,s,n,!0),o&&o.forEach((t=>gs(e,t,n,!0)));for(const o in t)if(r&&"expose"===o);else{const r=vs[o]||n&&n[o];e[o]=r?r(e[o],t[o]):t[o]}return e}const vs={data:ys,props:xs,emits:xs,methods:Ss,computed:Ss,beforeCreate:_s,created:_s,beforeMount:_s,mounted:_s,beforeUpdate:_s,updated:_s,beforeDestroy:_s,beforeUnmount:_s,destroyed:_s,unmounted:_s,activated:_s,deactivated:_s,errorCaptured:_s,serverPrefetch:_s,components:Ss,directives:Ss,watch:function(e,t){if(!e)return t;if(!t)return e;const n=f(Object.create(null),e);for(const r in t)n[r]=_s(e[r],t[r]);return n},provide:ys,inject:function(e,t){return Ss(bs(e),bs(t))}};function ys(e,t){return t?e?function(){return f(b(e)?e.call(this,this):e,b(t)?t.call(this,this):t)}:t:e}function bs(e){if(m(e)){const t={};for(let n=0;nString(e)===String(i))):de(t,i)>-1}else s.selected=t.has(i);else if(fe(ha(s),t))return void(e.selectedIndex!==n&&(e.selectedIndex=n))}r||-1===e.selectedIndex||(e.selectedIndex=-1)}}function ha(e){return"_value"in e?e._value:e.value}function ma(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const ga={created(e,t,n){ya(e,t,n,null,"created")},mounted(e,t,n){ya(e,t,n,null,"mounted")},beforeUpdate(e,t,n,r){ya(e,t,n,r,"beforeUpdate")},updated(e,t,n,r){ya(e,t,n,r,"updated")}};function va(e,t){switch(e){case"SELECT":return da;case"TEXTAREA":return la;default:switch(t){case"checkbox":return aa;case"radio":return fa;default:return la}}}function ya(e,t,n,r,o){const s=va(e.tagName,n.props&&n.props.type)[o];s&&s(e,t,n,r)}const ba=["ctrl","shift","alt","meta"],_a={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ba.some((n=>e[`${n}Key`]&&!t.includes(n)))},Sa=(e,t)=>{const n=e._withMods||(e._withMods={}),r=t.join(".");return n[r]||(n[r]=(n,...r)=>{for(let e=0;e
+
+
+
+fatalError): ?>
+
+
+
+
+
+
+fatalError): ?>
+
+
+
+
+
+
+fatalError): ?>
+
+
+
= e($file->sizeToString()) ?>
diff --git a/modules/backend/formwidgets/fileupload/partials/_image_single.php b/modules/backend/formwidgets/fileupload/partials/_image_single.php index b0c58ef86..cf5ce5c66 100644 --- a/modules/backend/formwidgets/fileupload/partials/_image_single.php +++ b/modules/backend/formwidgets/fileupload/partials/_image_single.php @@ -40,7 +40,7 @@ class="upload-button"> class="upload-remove-button" data-request="= $this->getEventHandler('onRemoveAttachment') ?>" data-request-confirm="= e(trans('backend::lang.fileupload.remove_confirm')) ?>" - data-request-data="file_id: = $singleFile->id ?>" + data-request-data="file_id: '= $singleFile->id ?>'" >= e($singleFile->sizeToString()) ?>
diff --git a/modules/backend/formwidgets/iconpicker/assets/js/dist/iconpicker.js b/modules/backend/formwidgets/iconpicker/assets/js/dist/iconpicker.js index 2760470e5..6f27b9199 100644 --- a/modules/backend/formwidgets/iconpicker/assets/js/dist/iconpicker.js +++ b/modules/backend/formwidgets/iconpicker/assets/js/dist/iconpicker.js @@ -1 +1 @@ -"use strict";(self.webpackChunk_wintercms_wn_backend_module=self.webpackChunk_wintercms_wn_backend_module||[]).push([[743],{595:function(e,i,t){var a=t(471);const o={class:"input-group"},d=["name"],n={key:0,class:"aim-modal aim-open"},l={class:"aim-modal--content"},r={class:"aim-modal--header"},c={class:"aim-modal--header-logo-area"},s={class:"aim-modal--header-logo-title"},m={class:"aim-modal--body"},p={class:"aim-modal--sidebar"},b={class:"aim-modal--sidebar-tabs"},u=["onClick"],h={class:"aim-sidebar-preview"},v={class:"aim-icon-item"},f={class:"aim-icon-item-inner"},x={class:"aim-icon-item-name"},g={class:"aim-modal--icon-preview-wrap"},w={class:"aim-modal--icon-search"},k=(e=>((0,a.pushScopeId)("data-v-5314cddb"),e=e(),(0,a.popScopeId)(),e))((()=>(0,a.createElementVNode)("i",{class:"icon-search"},null,-1))),y={class:"aim-modal--icon-preview-inner"},V={class:"aim-modal--icon-preview"},E=["onClick"],N={class:"aim-icon-item-inner"},P={class:"aim-icon-item-name"},z={class:"form-buttons normalized aim-modal--footer"};var O={inheritAttrs:!1,props:["label","propValue","name","fontLibraries"],data(){let e=this.propValue,i=e??"";const t=[{id:"all",title:"All Icons",icon:"fas icon-star-of-life",link:"all"}],a=[],o=[];return this.fontLibraries.forEach((e=>{t.push({id:e.id,title:e.title,icon:e.listicon,link:e}),a.push(e.prefix),o.push(...e.icons)})),-1===o.indexOf(e)&&(i=o[0]??""),{modelValue:e,activeGlyph:i,filterText:"",isVisible:!1,activeTab:t[0],prefixes:a,allGlyphs:o,tabs:t}},computed:{glyphs:{get(){let e=[];if(e="all"!==this.activeTab.id?this.activeTab.link.icons:this.allGlyphs,""!==this.filterText){const i=this.filterText.toLowerCase();e=e.filter((e=>e.includes(i)))}return e}}},methods:{setActiveGlyph(e){this.activeGlyph=e},isActiveGlyph(e){return this.activeGlyph===e},isActiveTab(e){return e===this.activeTab.id},setActiveTab(e){this.activeTab=e},getGlyphName:e=>e.replace(/f.. icon-/g,"").replaceAll("-"," "),insert(){this.modelValue=this.activeGlyph,this.isVisible=!1},togglePicker(){this.isVisible=!this.isVisible},closePicker(){this.isVisible=!1}}},C=t(62),A=t.n(C),T=t(780),j={insert:"head",singleton:!1};A()(T.Z,j),T.Z.locals;const S=(0,t(407).Z)(O,[["render",function(e,i,t,O,C,A){return(0,a.openBlock)(),(0,a.createElementBlock)(a.Fragment,null,[(0,a.createElementVNode)("div",o,[(0,a.createElementVNode)("span",{class:"input-group-addon",onClick:i[0]||(i[0]=function(){return A.togglePicker&&A.togglePicker(...arguments)}),style:{cursor:"pointer"}},[(0,a.createElementVNode)("i",{class:(0,a.normalizeClass)(C.modelValue)},null,2)]),(0,a.withDirectives)((0,a.createElementVNode)("input",{type:"text",class:"form-control","onUpdate:modelValue":i[1]||(i[1]=e=>C.modelValue=e),name:t.name,onClick:i[2]||(i[2]=function(){return A.togglePicker&&A.togglePicker(...arguments)})},null,8,d),[[a.vModelText,C.modelValue]])]),C.isVisible?((0,a.openBlock)(),(0,a.createElementBlock)("div",n,[(0,a.createElementVNode)("div",l,[(0,a.createElementVNode)("div",r,[(0,a.createElementVNode)("div",c,[(0,a.createElementVNode)("span",s,(0,a.toDisplayString)(t.label),1)])]),(0,a.createElementVNode)("div",m,[(0,a.createElementVNode)("div",p,[(0,a.createElementVNode)("div",b,[((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)(C.tabs,(e=>((0,a.openBlock)(),(0,a.createElementBlock)("div",{class:(0,a.normalizeClass)(["aim-modal--sidebar-tab-item",{"aesthetic-active":A.isActiveTab(e.id)}]),"data-library-id":"all",key:e.id,onClick:i=>A.setActiveTab(e)},[(0,a.createElementVNode)("i",{class:(0,a.normalizeClass)(e.icon)},null,2),(0,a.createElementVNode)("span",null,(0,a.toDisplayString)(e.title),1)],10,u)))),128))]),(0,a.createElementVNode)("div",h,[(0,a.createElementVNode)("div",v,[(0,a.createElementVNode)("div",f,[(0,a.createElementVNode)("i",{class:(0,a.normalizeClass)(C.activeGlyph)},null,2),(0,a.createElementVNode)("div",x,(0,a.toDisplayString)(A.getGlyphName(C.activeGlyph)),1)])])])]),(0,a.createElementVNode)("div",g,[(0,a.createElementVNode)("div",w,[(0,a.withDirectives)((0,a.createElementVNode)("input",{"onUpdate:modelValue":i[3]||(i[3]=e=>C.filterText=e),placeholder:"Filter by name..."},null,512),[[a.vModelText,C.filterText]]),k]),(0,a.createElementVNode)("div",y,[(0,a.createElementVNode)("div",V,[((0,a.openBlock)(!0),(0,a.createElementBlock)(a.Fragment,null,(0,a.renderList)(A.glyphs,(e=>((0,a.openBlock)(),(0,a.createElementBlock)("div",{class:(0,a.normalizeClass)(["aim-icon-item",{"aesthetic-selected":A.isActiveGlyph(e)}]),key:e,onClick:i=>A.setActiveGlyph(e)},[(0,a.createElementVNode)("div",N,[(0,a.createElementVNode)("i",{class:(0,a.normalizeClass)(e)},null,2),(0,a.createElementVNode)("div",P,(0,a.toDisplayString)(A.getGlyphName(e)),1)])],10,E)))),128))])])])]),(0,a.createElementVNode)("div",z,[(0,a.createElementVNode)("button",{class:"btn btn-primary aim-insert-icon-button",onClick:i[4]||(i[4]=function(){return A.insert&&A.insert(...arguments)})},"Insert"),(0,a.createElementVNode)("button",{class:"btn btn-secondary no-margin-right",onClick:i[5]||(i[5]=function(){return A.closePicker&&A.closePicker(...arguments)})},"Close")])])])):(0,a.createCommentVNode)("",!0)],64)}],["__scopeId","data-v-5314cddb"]]);var G=S;function B(e,i){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);i&&(a=a.filter((function(i){return Object.getOwnPropertyDescriptor(e,i).enumerable}))),t.push.apply(t,a)}return t}function D(e){for(var i=1;i