├── .env.example ├── .php-cs-fixer.php ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── art ├── banner.png ├── color-pickers.png └── swatches.png ├── composer.json ├── docker-compose.override.yml.dist ├── docker-compose.yml ├── docker └── workspace │ ├── Dockerfile │ └── php.ini ├── package-lock.json ├── package.json ├── phpstan.neon ├── ray.php ├── resources ├── css │ └── colorpicker.css ├── dist │ ├── filament-colorpicker.css │ └── filament-colorpicker.js ├── js │ └── colorpicker.ts ├── lang │ └── en │ │ └── swatch.php ├── types │ └── colorpicker.d.ts └── views │ ├── break.blade.php │ ├── clear-button.blade.php │ ├── color-swatch.blade.php │ ├── colorpicker.blade.php │ ├── preview.blade.php │ └── template.blade.php ├── rollup.config.js ├── src ├── Columns │ └── ColorSwatch.php ├── Enum │ ├── ColorPattern.php │ ├── EditorFormat.php │ └── PopupPosition.php ├── FilamentColorPickerServiceProvider.php └── Forms │ └── ColorPicker.php ├── tailwind.config.js └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | RAY_REMOTE_PATH=/var/www/html 2 | RAY_LOCAL_PATH= 3 | RAY_HOST=localhost 4 | -------------------------------------------------------------------------------- /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | setRiskyAllowed(true) 10 | ->setRules([ 11 | '@PSR2' => true, 12 | '@Symfony:risky' => true, 13 | '@PHP71Migration:risky' => true, 14 | '@PHP73Migration' => true, 15 | 'blank_line_after_opening_tag' => true, 16 | 'method_argument_space' => false, 17 | ]) 18 | ->setFinder((new PhpCsFixer\Finder()) 19 | ->in( 20 | array_map( 21 | static fn (string $dir) => __DIR__ . '/' . $dir, 22 | $dirs, 23 | ) 24 | ), 25 | ); 26 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `filament-colorpicker` will be documented in this file. 4 | 5 | ## v1.4.2 - So long, and thanks for all the fish! - 2022-04-21 6 | 7 | This release marks the deprecation of this package. Use [Filament's built-in colour picker instead](https://filamentphp.com/docs/2.x/forms/fields#color-picker) 8 | 9 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.4.1...1.4.2 10 | 11 | ## v1.4.1 - Add missing blade file - 2022-04-08 12 | 13 | ## What's Changed 14 | 15 | - Added missing blade file 16 | 17 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.4.0...1.4.1 18 | 19 | ## v1.4.0 - Nullable pickers - 2022-04-08 20 | 21 | ## What's Changed 22 | 23 | ### Added 24 | 25 | - Add support for `null` values 26 | 27 | ### Fixed 28 | 29 | - Fixed pickers with the popup disabled looking strange on larger screens 30 | 31 | ### Security 32 | 33 | - Bump minimist from 1.2.5 to 1.2.6 by @dependabot in https://github.com/RVxLab/filament-colorpicker/pull/16 34 | 35 | ## New Contributors 36 | 37 | - @dependabot made their first contribution in https://github.com/RVxLab/filament-colorpicker/pull/16 38 | 39 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.3.3...1.4.0 40 | 41 | ## v1.3.3 - Dark Mode and more reliable script loading - 2022-03-28 42 | 43 | ### What's Changed 44 | 45 | - Update colorpicker.blade.php by @invaders-xx in https://github.com/RVxLab/filament-colorpicker/pull/13 46 | - Improve script loading by using a promise 47 | 48 | ### New Contributors 49 | 50 | - @invaders-xx made their first contribution in https://github.com/RVxLab/filament-colorpicker/pull/13 51 | 52 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.3.2...1.3.3 53 | 54 | ## v1.3.2 - Allow multiple ColorPicker fields - 2022-03-18 55 | 56 | ### Fixes 57 | 58 | - Fixed the inability to have multiple ColorPicker fields in the same form 59 | 60 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.3.1...1.3.2 61 | 62 | ## v1.3.1 - 2022-03-15 63 | 64 | ### Fixed 65 | 66 | - fix: input not being initialized on simple resource modal by @saade in https://github.com/RVxLab/filament-colorpicker/pull/12 67 | 68 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.3.0...1.3.1 69 | 70 | ## 1.3.0 - 2022-03-05 71 | 72 | ### Added 73 | 74 | - Added a preview option by [@saade](https://github.com/saade) ([#11](https://github.com/RVxLab/filament-colorpicker/pull/11)) 75 | 76 | **Full Changelog**: https://github.com/RVxLab/filament-colorpicker/compare/1.2.1...1.3.0 77 | 78 | ## v1.2.1 - Fix dependencies and use of Js class - 2022-03-03 79 | 80 | ### Fixed 81 | 82 | - `illuminate/contract` now correctly states `^8.70` for the `Js` class and use the full FQN to prevent issues with aliases (#10) 83 | 84 | ## 1.2.0 - 2022-01-28 85 | 86 | - Add a swatch for use on tables ([#8](https://github.com/RVxLab/filament-colorpicker/pull/8)) 87 | 88 | Thanks to [@morganchorlton3](https://github.com/morganchorlton3) for adding this feature! 89 | 90 | ## 1.1.0 - 2022-01-26 91 | 92 | - Add Laravel 9 support 93 | 94 | ## 1.0.0 - 2022-01-18 95 | 96 | This release marks the first stable release of this package and targets Filament 2.x. 97 | 98 | An upgrade guide can be found in the README. 99 | 100 | - Update Filament dependency to `filament/filament:^2.0` 101 | - Add support for the `template` option 102 | - Allow the string representations of `EditorFormat` and `PopupPosition` to be passed as arguments to `editorFormat` and `popupPosition` respectively 103 | - Add a debounce for updating the value when the popup is disabled 104 | - Remove the ability to publish the JavaScript file 105 | 106 | ## 0.2.0 - 2021-07-11 107 | 108 | - Improved handling for disabled popups 109 | - Added validation and handling for RGB, RGBA, HSL and HSLA values 110 | - Added some tests 111 | 112 | ## 0.1.0 - 2021-06-13 113 | 114 | - First unstable release 115 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) rvxlab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: testbench 2 | 3 | EXEC="docker-compose exec -u app workspace" 4 | 5 | uid=1000 6 | gid=1000 7 | 8 | ## Docker 9 | up: 10 | docker-compose up -d 11 | 12 | start: up 13 | 14 | down: 15 | docker-compose down 16 | 17 | stop: down 18 | 19 | dcbuild: 20 | docker-compose build 21 | 22 | composer: 23 | "$(EXEC)" composer $(cmd) 24 | 25 | ## Artisan 26 | artisan: testbench 27 | 28 | testbench: 29 | "$(EXEC)" php vendor/bin/testbench $(cmd) 30 | 31 | ## Testing 32 | phpcsfixer: 33 | "$(EXEC)" vendor/bin/php-cs-fixer fix 34 | 35 | phpstan: 36 | "$(EXEC)" php -d memory_limit=-1 vendor/bin/phpstan analyze 37 | 38 | test: 39 | "$(EXEC)" vendor/bin/testbench package:test --parallel --no-coverage 40 | 41 | test-coverage: 42 | "$(EXEC)" vendor/bin/phpunit --coverage-html coverage 43 | 44 | test-all: phpstan phpcsfixer test 45 | 46 | ## Npm 47 | 48 | npm: 49 | "$(EXEC)" npm $(cmd) 50 | 51 | npm-dev: 52 | "$(EXEC)" npm run dev 53 | 54 | npm-watch: 55 | "$(EXEC)" npm run watch 56 | 57 | npm-prod: 58 | "$(EXEC)" npm run prod 59 | 60 | ## Misc 61 | sh: 62 | "$(EXEC)" sh 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Filament Color Picker 2 | 3 | ![Filament Color Picker](./art/banner.png) 4 | 5 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/rvxlab/filament-colorpicker.svg?style=flat-square)](https://packagist.org/packages/rvxlab/filament-colorpicker) 6 | [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/rvxlab/filament-colorpicker/run-tests?label=tests&style=flat-square)](https://github.com/rvxlab/filament-colorpicker/actions?query=workflow%3Arun-tests+branch%3Amain) 7 | [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/rvxlab/filament-colorpicker/Check%20&%20fix%20styling?label=code%20style&style=flat-square)](https://github.com/rvxlab/filament-colorpicker/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/rvxlab/filament-colorpicker.svg?style=flat-square)](https://packagist.org/packages/rvxlab/filament-colorpicker) 9 | 10 | --- 11 | 12 | # Deprecated 13 | 14 | **As of Filament v2.10.45 there's a built-in colour picker. Because of that I decided to deprecate this package and encourage everyone to use [the built-in colour picker instead](https://filamentphp.com/docs/2.x/forms/fields#color-picker). Thank you all for the support, bug reports and pull requests ❤️** 15 | 16 | --- 17 | 18 | Filament Color Picker is a package for [Laravel Filament](https://github.com/laravel-filament/filament) that wraps [Vanilla Picker](https://github.com/Sphinxxxx/vanilla-picker) into a usable component. 19 | 20 | ## Installation 21 | 22 | You can install the package via composer: 23 | 24 | ```bash 25 | composer require rvxlab/filament-colorpicker 26 | ``` 27 | 28 | Optionally you can publish the views: 29 | 30 | ```bash 31 | php artisan vendor:publish --tag=filament-colorpicker-views 32 | ``` 33 | 34 | ## Usage 35 | 36 | ![The color pickers in action](./art/color-pickers.png) 37 | 38 | Reference `RVxLab\FilamentColorPicker\Forms\ColorPicker` in the `forms` method of a resource and you're good to go! 39 | 40 | ```php 41 | public static function form(Form $form): Form 42 | { 43 | return $form 44 | ->schema([ 45 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color'), 46 | ]); 47 | } 48 | ``` 49 | 50 | All options below are analogous to the ones in the [Vanilla Picker documentation](https://vanilla-picker.js.org/gen/Picker.html#setOptions__anchor). 51 | 52 | ### Editor format 53 | 54 | ***Default:*** `EditorFormat::HEX()` 55 | 56 | Set the editor format of the color picker. 57 | 58 | ```php 59 | public static function form(Form $form): Form 60 | { 61 | return $form 62 | ->schema([ 63 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 64 | ->editorFormat(\RVxLab\FilamentColorPicker\Enum\EditorFormat::HSL()), 65 | ]); 66 | } 67 | ``` 68 | 69 | You may also pass the string values of the `EditorFormat` enum. 70 | 71 | ### Popup placement 72 | 73 | ***Default:*** `PopupPosition::RIGHT()` 74 | 75 | The popup placement can be set using `popupPosition`: 76 | 77 | ```php 78 | public static function form(Form $form): Form 79 | { 80 | return $form 81 | ->schema([ 82 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 83 | ->popupPosition(\RVxLab\FilamentColorPicker\Enum\PopupPosition::BOTTOM()), 84 | ]); 85 | } 86 | ``` 87 | 88 | You may also pass the string values of the `PopupPosition` enum. 89 | 90 | You can also disable the popup entirely in which the popup just becomes part of the element itself: 91 | 92 | ```php 93 | public static function form(Form $form): Form 94 | { 95 | return $form 96 | ->schema([ 97 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 98 | ->disablePopup(), 99 | ]); 100 | } 101 | ``` 102 | 103 | ### Alpha 104 | 105 | ***Default: true*** 106 | 107 | The alpha channel can be enabled or disabled by using `alpha`: 108 | 109 | ```php 110 | public static function form(Form $form): Form 111 | { 112 | return $form 113 | ->schema([ 114 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 115 | ->alpha(false), 116 | ]); 117 | } 118 | ``` 119 | 120 | An important thing to note is that the alpha setting also changes the validation. 121 | 122 | Having the alpha channel enabled will validate the output as an 8-digit hex string, disabling will validate it as a 6-digit hex string. 123 | 124 | ### Preview 125 | 126 | ***Default: false*** 127 | 128 | The color preview can be enabled or disabled by using `preview`: 129 | 130 | ```php 131 | public static function form(Form $form): Form 132 | { 133 | return $form 134 | ->schema([ 135 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 136 | ->preview(), 137 | ]); 138 | } 139 | ``` 140 | 141 | ### Layout 142 | 143 | ***Default: "default"*** 144 | 145 | The layout can be changed by using `layout`: 146 | 147 | ```php 148 | public static function form(Form $form): Form 149 | { 150 | return $form 151 | ->schema([ 152 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 153 | ->layout('my-layout'), 154 | ]); 155 | } 156 | ``` 157 | 158 | ### Cancel button 159 | 160 | ***Default: false*** 161 | 162 | The cancel button can be enabled or disabled by using `cancelButton`: 163 | 164 | ```php 165 | public static function form(Form $form): Form 166 | { 167 | return $form 168 | ->schema([ 169 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 170 | ->cancelButton(true), 171 | ]); 172 | } 173 | ``` 174 | 175 | ### Template 176 | 177 | ***Default: null*** 178 | 179 | The default template can be found in `views/vendor/filament-colorpicker/template.blade.php` after you publish the views. 180 | 181 | To make changes, simply change this template and then pass a `View` object to the `template` method: 182 | 183 | ```php 184 | public static function form(Form $form): Form 185 | { 186 | return $form 187 | ->schema([ 188 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 189 | ->template(view('filament-colorpicker::template')), 190 | ]); 191 | } 192 | ``` 193 | 194 | You can also pass an HTML string directly, which then gets fed to the options as is. 195 | 196 | ### Debounce timeout 197 | 198 | ***Default: 500*** 199 | 200 | The debounce timeout in milliseconds, this option is only applicable when the popup has been disabled. 201 | 202 | When the popup is enabled this option does nothing. 203 | 204 | ```php 205 | public static function form(Form $form): Form 206 | { 207 | return $form 208 | ->schema([ 209 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 210 | ->debounceTimeout(1000), 211 | ]); 212 | } 213 | ``` 214 | 215 | ### Nullable 216 | 217 | ***Default: false*** 218 | 219 | To make the color picker nullable you can call the `nullable` method: 220 | 221 | ```php 222 | public static function form(Form $form): Form 223 | { 224 | return $form 225 | ->schema([ 226 | \RVxLab\FilamentColorPicker\Forms\ColorPicker::make('color') 227 | ->nullable(), 228 | ]); 229 | } 230 | ``` 231 | 232 | #### Known issue 233 | 234 | Because Vanilla Picker does not handle null values properly the default initial value of a null-ed picker will be `#000000` or `#00000000` depending on the `alpha` setting. 235 | 236 | This goes away when the picker is updated or the form is saved. 237 | 238 | ## Color swatch 239 | 240 | ![The color pickers in action](./art/swatches.png) 241 | 242 | To display a swatch on the table you can add the following column: 243 | 244 | ```php 245 | public static function table(Table $table): Table 246 | { 247 | return $table 248 | ->columns([ 249 | \RVxLab\FilamentColorPicker\Columns\ColorSwatch::make('color'), 250 | ]); 251 | } 252 | ``` 253 | 254 | ### Copying 255 | 256 | *Note: this makes use of the [clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard).* 257 | 258 | You can call the `copyable` method on the column: 259 | 260 | ```php 261 | public static function table(Table $table): Table 262 | { 263 | return $table 264 | ->columns([ 265 | \RVxLab\FilamentColorPicker\Columns\ColorSwatch::make('color') 266 | ->copyable(), 267 | ]); 268 | } 269 | ``` 270 | 271 | When set, clicking on the swatch will cause the current color to be copied to the clipboard. 272 | 273 | ### Set the copy message 274 | 275 | ***Default: "Copied!"*** 276 | 277 | You can change the copy message by using the `copyMessage` method: 278 | 279 | ```php 280 | public static function table(Table $table): Table 281 | { 282 | return $table 283 | ->columns([ 284 | \RVxLab\FilamentColorPicker\Columns\ColorSwatch::make('color') 285 | ->copyable() 286 | ->copyMessage('Color copied to clipboard!'), 287 | ]); 288 | } 289 | ``` 290 | 291 | ### Change the message timeout 292 | 293 | ***Default: 2000*** 294 | 295 | To change the length of time the message appears you can use the `copyMessageShowTimeMs` method: 296 | 297 | ```php 298 | public static function table(Table $table): Table 299 | { 300 | return $table 301 | ->columns([ 302 | \RVxLab\FilamentColorPicker\Columns\ColorSwatch::make('color') 303 | ->copyable() 304 | ->copyMessageShowTimeMs(500), 305 | ]); 306 | } 307 | ``` 308 | 309 | ## Changelog 310 | 311 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 312 | 313 | ## Upgrading to 1.x 314 | 315 | The only breaking change is that this package now relies on `filament/filament:^2.0`, other than that there are no breaking changes. 316 | 317 | If you published the JavaScript file in the past you can delete it, the file is now loaded through Filament directly 318 | 319 | ## Contributing 320 | 321 | For development this repository contains a Docker Compose file to provide all the tools needed, as well as a Makefile to run useful commands. 322 | 323 | To make use of this, ensure you have Docker and Docker Compose installed. 324 | 325 | To get started: 326 | 327 | ```bash 328 | make dcbuild # Build the Docker image 329 | make start # Run the container 330 | make composer cmd=install 331 | ``` 332 | 333 | Additionally you can copy and modify `docker-compose.override.yml.dist` to add any additional changes needed for the workspace container. 334 | 335 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 336 | 337 | ## Credits 338 | 339 | - [RVxLab](https://github.com/RVxLab) 340 | - [All Contributors](../../contributors) 341 | 342 | ## License 343 | 344 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 345 | -------------------------------------------------------------------------------- /art/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVxLab/filament-colorpicker/144627106666b2b2bd84a52828c6fb5db48bdd03/art/banner.png -------------------------------------------------------------------------------- /art/color-pickers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVxLab/filament-colorpicker/144627106666b2b2bd84a52828c6fb5db48bdd03/art/color-pickers.png -------------------------------------------------------------------------------- /art/swatches.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVxLab/filament-colorpicker/144627106666b2b2bd84a52828c6fb5db48bdd03/art/swatches.png -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rvxlab/filament-colorpicker", 3 | "description": "A color picker package for Laravel Filament", 4 | "keywords": [ 5 | "laravel", 6 | "colorpicker", 7 | "filament", 8 | "vanilla-picker" 9 | ], 10 | "homepage": "https://github.com/rvxlab/filament-colorpicker", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "RVxLab", 15 | "email": "richard@rvx.works", 16 | "role": "Developer" 17 | } 18 | ], 19 | "require": { 20 | "php": "^8.0", 21 | "filament/filament": "^2.7", 22 | "illuminate/contracts": "^8.71|^9.0", 23 | "myclabs/php-enum": "^1.8", 24 | "spatie/laravel-package-tools": "^1.4.3" 25 | }, 26 | "require-dev": { 27 | "brianium/paratest": "^6.2", 28 | "friendsofphp/php-cs-fixer": "^3.0", 29 | "nunomaduro/collision": "^5|^6", 30 | "nunomaduro/larastan": "^1.0", 31 | "orchestra/testbench": "^6.15|^7.0", 32 | "phpstan/extension-installer": "^1.1", 33 | "phpstan/phpstan-phpunit": "^1.0", 34 | "phpunit/phpunit": "^9.3", 35 | "roave/security-advisories": "dev-latest", 36 | "spatie/laravel-ray": "^1.23", 37 | "symfony/console": "^5|~6.0" 38 | }, 39 | "autoload": { 40 | "psr-4": { 41 | "RVxLab\\FilamentColorPicker\\": "src" 42 | } 43 | }, 44 | "autoload-dev": { 45 | "psr-4": { 46 | "RVxLab\\FilamentColorPicker\\Tests\\": "tests" 47 | } 48 | }, 49 | "config": { 50 | "sort-packages": true, 51 | "allow-plugins": { 52 | "phpstan/extension-installer": true 53 | } 54 | }, 55 | "extra": { 56 | "laravel": { 57 | "providers": [ 58 | "RVxLab\\FilamentColorPicker\\FilamentColorPickerServiceProvider" 59 | ] 60 | } 61 | }, 62 | "abandoned": "filament/forms", 63 | "minimum-stability": "dev", 64 | "prefer-stable": true 65 | } 66 | -------------------------------------------------------------------------------- /docker-compose.override.yml.dist: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | workspace: 4 | 5 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | workspace: 4 | build: 5 | context: ./docker/workspace 6 | dockerfile: Dockerfile 7 | args: 8 | PUID: '${PUID:-1000}' 9 | PGID: '${PGID:-1000}' 10 | environment: 11 | RAY_REMOTE_PATH: ${RAY_REMOTE_PATH:-localhost} 12 | RAY_LOCAL_PATH: ${RAY_LOCAL_PATH} 13 | RAY_HOST: ${RAY_HOST} 14 | volumes: 15 | - '.:/var/www/html' 16 | - '~/.composer:/home/app/.composer' 17 | tty: true 18 | extra_hosts: 19 | - "${RAY_HOST-127.0.0.1}:host-gateway" 20 | -------------------------------------------------------------------------------- /docker/workspace/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.0-cli-alpine 2 | 3 | ARG PUID=1000 4 | ARG PGID=1000 5 | 6 | # Install needed packages 7 | RUN apk add -u --no-cache \ 8 | # Curl for HTTP requests 9 | curl \ 10 | # Zip utilities for Composer 11 | zip unzip \ 12 | # Git for... you know... git 13 | git \ 14 | # libpng for GD 15 | libpng-dev \ 16 | # python2 for node-gyp 17 | python2 \ 18 | # Build utilities 19 | autoconf g++ make 20 | 21 | # Install PHP extensions 22 | RUN pecl install pcov \ 23 | && docker-php-ext-enable pcov 24 | 25 | # Composer 26 | COPY --from=composer /usr/bin/composer /usr/bin/composer 27 | 28 | # Node 29 | COPY --from=node:15-alpine /usr/local/bin/node /usr/local/bin/node 30 | COPY --from=node:15-alpine /usr/local/lib/node_modules /usr/local/lib/node_modules 31 | RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ 32 | && ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx 33 | 34 | # Set up non-root 35 | RUN addgroup -g $PGID app \ 36 | && adduser -D -h /home/app -G app -u $PUID app 37 | 38 | # Custom PHP config 39 | COPY php.ini /usr/local/etc/php/conf.d/ 40 | 41 | # Create directory for code coverage within PhpStorm 42 | RUN mkdir /opt/phpstorm-coverage && chown app:app /opt/phpstorm-coverage 43 | 44 | # Let's do this 45 | USER app 46 | WORKDIR /var/www/html 47 | -------------------------------------------------------------------------------- /docker/workspace/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | post_max_size = 100M 3 | upload_max_filesize = 100M 4 | variables_order = EGPCS 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev": "rollup -c", 4 | "watch": "rollup -cw", 5 | "prod": "rollup -c --environment BUILD:production" 6 | }, 7 | "dependencies": { 8 | "lodash": "^4.17.21", 9 | "vanilla-picker": "^2.11.2" 10 | }, 11 | "devDependencies": { 12 | "@rollup/plugin-commonjs": "^19.0.0", 13 | "@rollup/plugin-node-resolve": "^13.0.0", 14 | "@rollup/plugin-typescript": "^8.3.1", 15 | "@types/alpinejs": "^3.7.0", 16 | "@types/lodash": "^4.14.178", 17 | "autoprefixer": "^10.4.2", 18 | "rollup": "^2.51.2", 19 | "rollup-plugin-postcss": "^4.0.2", 20 | "rollup-plugin-terser": "^7.0.2", 21 | "tailwindcss": "^3.0.23", 22 | "tslib": "^2.3.1", 23 | "typescript": "^4.6.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | paths: 3 | - src 4 | - tests 5 | 6 | level: max 7 | -------------------------------------------------------------------------------- /ray.php: -------------------------------------------------------------------------------- 1 | env('RAY_ENABLED', true), 12 | 13 | /* 14 | * When enabled, all cache events will automatically be sent to Ray. 15 | */ 16 | 'send_cache_to_ray' => env('SEND_CACHE_TO_RAY', false), 17 | 18 | /* 19 | * When enabled, all things passed to `dump` or `dd` 20 | * will be sent to Ray as well. 21 | */ 22 | 'send_dumps_to_ray' => env('SEND_DUMPS_TO_RAY', true), 23 | 24 | /* 25 | * When enabled all job events will automatically be sent to Ray. 26 | */ 27 | 'send_jobs_to_ray' => env('SEND_JOBS_TO_RAY', false), 28 | 29 | /* 30 | * When enabled, all things logged to the application log 31 | * will be sent to Ray as well. 32 | */ 33 | 'send_log_calls_to_ray' => env('SEND_LOG_CALLS_TO_RAY', true), 34 | 35 | /* 36 | * When enabled, all queries will automatically be sent to Ray. 37 | */ 38 | 'send_queries_to_ray' => env('SEND_QUERIES_TO_RAY', false), 39 | 40 | /* 41 | * When enabled, all requests made to this app will automatically be sent to Ray. 42 | */ 43 | 'send_requests_to_ray' => env('SEND_REQUESTS_TO_RAY', false), 44 | 45 | /* 46 | * When enabled, all views that are rendered automatically be sent to Ray. 47 | */ 48 | 'send_views_to_ray' => env('SEND_VIEWS_TO_RAY', false), 49 | 50 | /* 51 | * When enabled, all exceptions will be automatically sent to Ray. 52 | */ 53 | 'send_exceptions_to_ray' => env('SEND_EXCEPTIONS_TO_RAY', true), 54 | 55 | /* 56 | * The host used to communicate with the Ray app. 57 | * When using Docker on Mac or Windows, you can replace localhost with 'host.docker.internal' 58 | * When using Homestead with the VirtualBox provider, you can replace localhost with '10.0.2.2' 59 | * When using Homestead with the Parallels provider, you can replace localhost with '10.211.55.2' 60 | */ 61 | 'host' => env('RAY_HOST', 'localhost'), 62 | 63 | /* 64 | * The port number used to communicate with the Ray app. 65 | */ 66 | 'port' => env('RAY_PORT', 23517), 67 | 68 | /* 69 | * Absolute base path for your sites or projects in Homestead, 70 | * Vagrant, Docker, or another remote development server. 71 | */ 72 | 'remote_path' => env('RAY_REMOTE_PATH', null), 73 | 74 | /* 75 | * Absolute base path for your sites or projects on your local 76 | * computer where your IDE or code editor is running on. 77 | */ 78 | 'local_path' => env('RAY_LOCAL_PATH', null), 79 | 80 | /* 81 | * When this setting is enabled, the package will not try to format values sent to Ray. 82 | */ 83 | 'always_send_raw_values' => false, 84 | ]; 85 | -------------------------------------------------------------------------------- /resources/css/colorpicker.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind utilities; 3 | 4 | .color-picker-preview { 5 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAZQTFRFqamp////1p50kwAAABRJREFUeJxjYLD/wEAM/n+AgRgMACSCHU0RydcxAAAAAElFTkSuQmCC); 6 | } 7 | 8 | .color-picker .picker_wrapper::before { 9 | flex-basis: 100%; 10 | height: 0; 11 | } 12 | -------------------------------------------------------------------------------- /resources/dist/filament-colorpicker.css: -------------------------------------------------------------------------------- 1 | /* 2 | ! tailwindcss v3.0.23 | MIT License | https://tailwindcss.com 3 | */*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-family: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%;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}*,:after,:before{--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: }.rvx-top-2{top:.5rem}.rvx-right-2{right:.5rem}.rvx-h-\[42px\]{height:42px}.\!rvx-rounded-r-lg{border-bottom-right-radius:.5rem!important;border-top-right-radius:.5rem!important}.rvx-rounded-l-lg{border-bottom-left-radius:.5rem;border-top-left-radius:.5rem}.\!rvx-border-r-0{border-right-width:0!important}.color-picker-preview{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAZQTFRFqamp////1p50kwAAABRJREFUeJxjYLD/wEAM/n+AgRgMACSCHU0RydcxAAAAAElFTkSuQmCC)}.color-picker .picker_wrapper:before{flex-basis:100%;height:0} -------------------------------------------------------------------------------- /resources/dist/filament-colorpicker.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var t,n,r="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},e={exports:{}}; 2 | /** 3 | * @license 4 | * Lodash 5 | * Copyright OpenJS Foundation and other contributors 6 | * Released under MIT license 7 | * Based on Underscore.js 1.8.3 8 | * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 9 | */ 10 | t=e,n=e.exports,function(){var e,i="Expected a function",u="__lodash_hash_undefined__",o="__lodash_placeholder__",a=16,c=32,f=64,l=128,s=256,p=1/0,h=9007199254740991,v=NaN,_=4294967295,d=[["ary",l],["bind",1],["bindKey",2],["curry",8],["curryRight",a],["flip",512],["partial",c],["partialRight",f],["rearg",s]],g="[object Arguments]",y="[object Array]",b="[object Boolean]",m="[object Date]",w="[object Error]",k="[object Function]",x="[object GeneratorFunction]",E="[object Map]",S="[object Number]",A="[object Object]",j="[object Promise]",C="[object RegExp]",L="[object Set]",O="[object String]",R="[object Symbol]",I="[object WeakMap]",z="[object ArrayBuffer]",T="[object DataView]",D="[object Float32Array]",W="[object Float64Array]",$="[object Int8Array]",B="[object Int16Array]",U="[object Int32Array]",H="[object Uint8Array]",M="[object Uint8ClampedArray]",P="[object Uint16Array]",F="[object Uint32Array]",q=/\b__p \+= '';/g,N=/\b(__p \+=) '' \+/g,V=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Z=/&(?:amp|lt|gt|quot|#39);/g,G=/[&<>"']/g,K=RegExp(Z.source),Y=RegExp(G.source),J=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,tt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nt=/^\w*$/,rt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,et=/[\\^$.*+?()[\]{}|]/g,it=RegExp(et.source),ut=/^\s+/,ot=/\s/,at=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,ct=/\{\n\/\* \[wrapped with (.+)\] \*/,ft=/,? & /,lt=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,st=/[()=,{}\[\]\/\s]/,pt=/\\(\\)?/g,ht=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,vt=/\w*$/,_t=/^[-+]0x[0-9a-f]+$/i,dt=/^0b[01]+$/i,gt=/^\[object .+?Constructor\]$/,yt=/^0o[0-7]+$/i,bt=/^(?:0|[1-9]\d*)$/,mt=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,wt=/($^)/,kt=/['\n\r\u2028\u2029\\]/g,xt="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Et="\\u2700-\\u27bf",St="a-z\\xdf-\\xf6\\xf8-\\xff",At="A-Z\\xc0-\\xd6\\xd8-\\xde",jt="\\ufe0e\\ufe0f",Ct="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",Lt="['’]",Ot="[\\ud800-\\udfff]",Rt="["+Ct+"]",It="["+xt+"]",zt="\\d+",Tt="[\\u2700-\\u27bf]",Dt="["+St+"]",Wt="[^\\ud800-\\udfff"+Ct+zt+Et+St+At+"]",$t="\\ud83c[\\udffb-\\udfff]",Bt="[^\\ud800-\\udfff]",Ut="(?:\\ud83c[\\udde6-\\uddff]){2}",Ht="[\\ud800-\\udbff][\\udc00-\\udfff]",Mt="["+At+"]",Pt="(?:"+Dt+"|"+Wt+")",Ft="(?:"+Mt+"|"+Wt+")",qt="(?:['’](?:d|ll|m|re|s|t|ve))?",Nt="(?:['’](?:D|LL|M|RE|S|T|VE))?",Vt="(?:"+It+"|"+$t+")?",Zt="[\\ufe0e\\ufe0f]?",Gt=Zt+Vt+"(?:\\u200d(?:"+[Bt,Ut,Ht].join("|")+")"+Zt+Vt+")*",Kt="(?:"+[Tt,Ut,Ht].join("|")+")"+Gt,Yt="(?:"+[Bt+It+"?",It,Ut,Ht,Ot].join("|")+")",Jt=RegExp(Lt,"g"),Xt=RegExp(It,"g"),Qt=RegExp($t+"(?="+$t+")|"+Yt+Gt,"g"),tn=RegExp([Mt+"?"+Dt+"+"+qt+"(?="+[Rt,Mt,"$"].join("|")+")",Ft+"+"+Nt+"(?="+[Rt,Mt+Pt,"$"].join("|")+")",Mt+"?"+Pt+"+"+qt,Mt+"+"+Nt,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",zt,Kt].join("|"),"g"),nn=RegExp("[\\u200d\\ud800-\\udfff"+xt+jt+"]"),rn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,en=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],un=-1,on={};on[D]=on[W]=on[$]=on[B]=on[U]=on[H]=on[M]=on[P]=on[F]=!0,on[g]=on[y]=on[z]=on[b]=on[T]=on[m]=on[w]=on[k]=on[E]=on[S]=on[A]=on[C]=on[L]=on[O]=on[I]=!1;var an={};an[g]=an[y]=an[z]=an[T]=an[b]=an[m]=an[D]=an[W]=an[$]=an[B]=an[U]=an[E]=an[S]=an[A]=an[C]=an[L]=an[O]=an[R]=an[H]=an[M]=an[P]=an[F]=!0,an[w]=an[k]=an[I]=!1;var cn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},fn=parseFloat,ln=parseInt,sn="object"==typeof r&&r&&r.Object===Object&&r,pn="object"==typeof self&&self&&self.Object===Object&&self,hn=sn||pn||Function("return this")(),vn=n&&!n.nodeType&&n,_n=vn&&t&&!t.nodeType&&t,dn=_n&&_n.exports===vn,gn=dn&&sn.process,yn=function(){try{var t=_n&&_n.require&&_n.require("util").types;return t||gn&&gn.binding&&gn.binding("util")}catch(t){}}(),bn=yn&&yn.isArrayBuffer,mn=yn&&yn.isDate,wn=yn&&yn.isMap,kn=yn&&yn.isRegExp,xn=yn&&yn.isSet,En=yn&&yn.isTypedArray;function Sn(t,n,r){switch(r.length){case 0:return t.call(n);case 1:return t.call(n,r[0]);case 2:return t.call(n,r[0],r[1]);case 3:return t.call(n,r[0],r[1],r[2])}return t.apply(n,r)}function An(t,n,r,e){for(var i=-1,u=null==t?0:t.length;++i-1}function In(t,n,r){for(var e=-1,i=null==t?0:t.length;++e-1;);return r}function nr(t,n){for(var r=t.length;r--&&Mn(n,t[r],0)>-1;);return r}function rr(t,n){for(var r=t.length,e=0;r--;)t[r]===n&&++e;return e}var er=Vn({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"}),ir=Vn({"&":"&","<":"<",">":">",'"':""","'":"'"});function ur(t){return"\\"+cn[t]}function or(t){return nn.test(t)}function ar(t){var n=-1,r=Array(t.size);return t.forEach((function(t,e){r[++n]=[e,t]})),r}function cr(t,n){return function(r){return t(n(r))}}function fr(t,n){for(var r=-1,e=t.length,i=0,u=[];++r",""":'"',"'":"'"}),dr=function t(n){var r,ot=(n=null==n?hn:dr.defaults(hn.Object(),n,dr.pick(hn,en))).Array,xt=n.Date,Et=n.Error,St=n.Function,At=n.Math,jt=n.Object,Ct=n.RegExp,Lt=n.String,Ot=n.TypeError,Rt=ot.prototype,It=St.prototype,zt=jt.prototype,Tt=n["__core-js_shared__"],Dt=It.toString,Wt=zt.hasOwnProperty,$t=0,Bt=(r=/[^.]+$/.exec(Tt&&Tt.keys&&Tt.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"",Ut=zt.toString,Ht=Dt.call(jt),Mt=hn._,Pt=Ct("^"+Dt.call(Wt).replace(et,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Ft=dn?n.Buffer:e,qt=n.Symbol,Nt=n.Uint8Array,Vt=Ft?Ft.allocUnsafe:e,Zt=cr(jt.getPrototypeOf,jt),Gt=jt.create,Kt=zt.propertyIsEnumerable,Yt=Rt.splice,Qt=qt?qt.isConcatSpreadable:e,nn=qt?qt.iterator:e,cn=qt?qt.toStringTag:e,sn=function(){try{var t=hu(jt,"defineProperty");return t({},"",{}),t}catch(t){}}(),pn=n.clearTimeout!==hn.clearTimeout&&n.clearTimeout,vn=xt&&xt.now!==hn.Date.now&&xt.now,_n=n.setTimeout!==hn.setTimeout&&n.setTimeout,gn=At.ceil,yn=At.floor,Bn=jt.getOwnPropertySymbols,Vn=Ft?Ft.isBuffer:e,gr=n.isFinite,yr=Rt.join,br=cr(jt.keys,jt),mr=At.max,wr=At.min,kr=xt.now,xr=n.parseInt,Er=At.random,Sr=Rt.reverse,Ar=hu(n,"DataView"),jr=hu(n,"Map"),Cr=hu(n,"Promise"),Lr=hu(n,"Set"),Or=hu(n,"WeakMap"),Rr=hu(jt,"create"),Ir=Or&&new Or,zr={},Tr=Hu(Ar),Dr=Hu(jr),Wr=Hu(Cr),$r=Hu(Lr),Br=Hu(Or),Ur=qt?qt.prototype:e,Hr=Ur?Ur.valueOf:e,Mr=Ur?Ur.toString:e;function Pr(t){if(ia(t)&&!Zo(t)&&!(t instanceof Vr)){if(t instanceof Nr)return t;if(Wt.call(t,"__wrapped__"))return Mu(t)}return new Nr(t)}var Fr=function(){function t(){}return function(n){if(!ea(n))return{};if(Gt)return Gt(n);t.prototype=n;var r=new t;return t.prototype=e,r}}();function qr(){}function Nr(t,n){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!n,this.__index__=0,this.__values__=e}function Vr(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=_,this.__views__=[]}function Zr(t){var n=-1,r=null==t?0:t.length;for(this.clear();++n=n?t:n)),t}function le(t,n,r,i,u,o){var a,c=1&n,f=2&n,l=4&n;if(r&&(a=u?r(t,i,u,o):r(t)),a!==e)return a;if(!ea(t))return t;var s=Zo(t);if(s){if(a=function(t){var n=t.length,r=new t.constructor(n);return n&&"string"==typeof t[0]&&Wt.call(t,"index")&&(r.index=t.index,r.input=t.input),r}(t),!c)return Ri(t,a)}else{var p=du(t),h=p==k||p==x;if(Jo(t))return Si(t,c);if(p==A||p==g||h&&!u){if(a=f||h?{}:yu(t),!c)return f?function(t,n){return Ii(t,_u(t),n)}(t,function(t,n){return t&&Ii(n,Da(n),t)}(a,t)):function(t,n){return Ii(t,vu(t),n)}(t,oe(a,t))}else{if(!an[p])return u?t:{};a=function(t,n,r){var e,i=t.constructor;switch(n){case z:return Ai(t);case b:case m:return new i(+t);case T:return function(t,n){var r=n?Ai(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)}(t,r);case D:case W:case $:case B:case U:case H:case M:case P:case F:return ji(t,r);case E:return new i;case S:case O:return new i(t);case C:return function(t){var n=new t.constructor(t.source,vt.exec(t));return n.lastIndex=t.lastIndex,n}(t);case L:return new i;case R:return e=t,Hr?jt(Hr.call(e)):{}}}(t,p,c)}}o||(o=new Jr);var v=o.get(t);if(v)return v;o.set(t,a),fa(t)?t.forEach((function(e){a.add(le(e,n,r,e,t,o))})):ua(t)&&t.forEach((function(e,i){a.set(i,le(e,n,r,i,t,o))}));var _=s?e:(l?f?ou:uu:f?Da:Ta)(t);return jn(_||t,(function(e,i){_&&(e=t[i=e]),ee(a,i,le(e,n,r,i,t,o))})),a}function se(t,n,r){var i=r.length;if(null==t)return!i;for(t=jt(t);i--;){var u=r[i],o=n[u],a=t[u];if(a===e&&!(u in t)||!o(a))return!1}return!0}function pe(t,n,r){if("function"!=typeof t)throw new Ot(i);return zu((function(){t.apply(e,r)}),n)}function he(t,n,r,e){var i=-1,u=Rn,o=!0,a=t.length,c=[],f=n.length;if(!a)return c;r&&(n=zn(n,Jn(r))),e?(u=In,o=!1):n.length>=200&&(u=Qn,o=!1,n=new Yr(n));t:for(;++i-1},Gr.prototype.set=function(t,n){var r=this.__data__,e=ie(r,t);return e<0?(++this.size,r.push([t,n])):r[e][1]=n,this},Kr.prototype.clear=function(){this.size=0,this.__data__={hash:new Zr,map:new(jr||Gr),string:new Zr}},Kr.prototype.delete=function(t){var n=su(this,t).delete(t);return this.size-=n?1:0,n},Kr.prototype.get=function(t){return su(this,t).get(t)},Kr.prototype.has=function(t){return su(this,t).has(t)},Kr.prototype.set=function(t,n){var r=su(this,t),e=r.size;return r.set(t,n),this.size+=r.size==e?0:1,this},Yr.prototype.add=Yr.prototype.push=function(t){return this.__data__.set(t,u),this},Yr.prototype.has=function(t){return this.__data__.has(t)},Jr.prototype.clear=function(){this.__data__=new Gr,this.size=0},Jr.prototype.delete=function(t){var n=this.__data__,r=n.delete(t);return this.size=n.size,r},Jr.prototype.get=function(t){return this.__data__.get(t)},Jr.prototype.has=function(t){return this.__data__.has(t)},Jr.prototype.set=function(t,n){var r=this.__data__;if(r instanceof Gr){var e=r.__data__;if(!jr||e.length<199)return e.push([t,n]),this.size=++r.size,this;r=this.__data__=new Kr(e)}return r.set(t,n),this.size=r.size,this};var ve=Di(ke),_e=Di(xe,!0);function de(t,n){var r=!0;return ve(t,(function(t,e,i){return r=!!n(t,e,i)})),r}function ge(t,n,r){for(var i=-1,u=t.length;++i0&&r(a)?n>1?be(a,n-1,r,e,i):Tn(i,a):e||(i[i.length]=a)}return i}var me=Wi(),we=Wi(!0);function ke(t,n){return t&&me(t,n,Ta)}function xe(t,n){return t&&we(t,n,Ta)}function Ee(t,n){return On(n,(function(n){return ta(t[n])}))}function Se(t,n){for(var r=0,i=(n=wi(n,t)).length;null!=t&&rn}function Le(t,n){return null!=t&&Wt.call(t,n)}function Oe(t,n){return null!=t&&n in jt(t)}function Re(t,n,r){for(var i=r?In:Rn,u=t[0].length,o=t.length,a=o,c=ot(o),f=1/0,l=[];a--;){var s=t[a];a&&n&&(s=zn(s,Jn(n))),f=wr(s.length,f),c[a]=!r&&(n||u>=120&&s.length>=120)?new Yr(a&&s):e}s=t[0];var p=-1,h=c[0];t:for(;++p=a?c:c*("desc"==r[e]?-1:1)}return t.index-n.index}(t,n,r)}))}function Ze(t,n,r){for(var e=-1,i=n.length,u={};++e-1;)a!==t&&Yt.call(a,c,1),Yt.call(t,c,1);return t}function Ke(t,n){for(var r=t?n.length:0,e=r-1;r--;){var i=n[r];if(r==e||i!==u){var u=i;mu(i)?Yt.call(t,i,1):hi(t,i)}}return t}function Ye(t,n){return t+yn(Er()*(n-t+1))}function Je(t,n){var r="";if(!t||n<1||n>h)return r;do{n%2&&(r+=t),(n=yn(n/2))&&(t+=t)}while(n);return r}function Xe(t,n){return Tu(Cu(t,n,oc),t+"")}function Qe(t){return Qr(Fa(t))}function ti(t,n){var r=Fa(t);return $u(r,fe(n,0,r.length))}function ni(t,n,r,i){if(!ea(t))return t;for(var u=-1,o=(n=wi(n,t)).length,a=o-1,c=t;null!=c&&++ui?0:i+n),(r=r>i?i:r)<0&&(r+=i),i=n>r?0:r-n>>>0,n>>>=0;for(var u=ot(i);++e>>1,o=t[u];null!==o&&!sa(o)&&(r?o<=n:o=200){var f=n?null:Ji(t);if(f)return lr(f);o=!1,i=Qn,c=new Yr}else c=n?[]:a;t:for(;++e=i?t:ui(t,n,r)}var Ei=pn||function(t){return hn.clearTimeout(t)};function Si(t,n){if(n)return t.slice();var r=t.length,e=Vt?Vt(r):new t.constructor(r);return t.copy(e),e}function Ai(t){var n=new t.constructor(t.byteLength);return new Nt(n).set(new Nt(t)),n}function ji(t,n){var r=n?Ai(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}function Ci(t,n){if(t!==n){var r=t!==e,i=null===t,u=t==t,o=sa(t),a=n!==e,c=null===n,f=n==n,l=sa(n);if(!c&&!l&&!o&&t>n||o&&a&&f&&!c&&!l||i&&a&&f||!r&&f||!u)return 1;if(!i&&!o&&!l&&t1?r[u-1]:e,a=u>2?r[2]:e;for(o=t.length>3&&"function"==typeof o?(u--,o):e,a&&wu(r[0],r[1],a)&&(o=u<3?e:o,u=1),n=jt(n);++i-1?u[o?n[a]:a]:e}}function Mi(t){return iu((function(n){var r=n.length,u=r,o=Nr.prototype.thru;for(t&&n.reverse();u--;){var a=n[u];if("function"!=typeof a)throw new Ot(i);if(o&&!c&&"wrapper"==cu(a))var c=new Nr([],!0)}for(u=c?u:r;++u1&&y.reverse(),p&&fc))return!1;var l=o.get(t),s=o.get(n);if(l&&s)return l==n&&s==t;var p=-1,h=!0,v=2&r?new Yr:e;for(o.set(t,n),o.set(n,t);++p-1&&t%1==0&&t1?"& ":"")+n[e],n=n.join(r>2?", ":" "),t.replace(at,"{\n/* [wrapped with "+n+"] */\n")}(e,function(t,n){return jn(d,(function(r){var e="_."+r[0];n&r[1]&&!Rn(t,e)&&t.push(e)})),t.sort()}(function(t){var n=t.match(ct);return n?n[1].split(ft):[]}(e),r)))}function Wu(t){var n=0,r=0;return function(){var i=kr(),u=16-(i-r);if(r=i,u>0){if(++n>=800)return arguments[0]}else n=0;return t.apply(e,arguments)}}function $u(t,n){var r=-1,i=t.length,u=i-1;for(n=n===e?i:n;++r1?t[n-1]:e;return r="function"==typeof r?(t.pop(),r):e,ao(t,r)}));function vo(t){var n=Pr(t);return n.__chain__=!0,n}function _o(t,n){return n(t)}var go=iu((function(t){var n=t.length,r=n?t[0]:0,i=this.__wrapped__,u=function(n){return ce(n,t)};return!(n>1||this.__actions__.length)&&i instanceof Vr&&mu(r)?((i=i.slice(r,+r+(n?1:0))).__actions__.push({func:_o,args:[u],thisArg:e}),new Nr(i,this.__chain__).thru((function(t){return n&&!t.length&&t.push(e),t}))):this.thru(u)})),yo=zi((function(t,n,r){Wt.call(t,r)?++t[r]:ae(t,r,1)})),bo=Hi(Nu),mo=Hi(Vu);function wo(t,n){return(Zo(t)?jn:ve)(t,lu(n,3))}function ko(t,n){return(Zo(t)?Cn:_e)(t,lu(n,3))}var xo=zi((function(t,n,r){Wt.call(t,r)?t[r].push(n):ae(t,r,[n])})),Eo=Xe((function(t,n,r){var e=-1,i="function"==typeof n,u=Ko(t)?ot(t.length):[];return ve(t,(function(t){u[++e]=i?Sn(n,t,r):Ie(t,n,r)})),u})),So=zi((function(t,n,r){ae(t,r,n)}));function Ao(t,n){return(Zo(t)?zn:Me)(t,lu(n,3))}var jo=zi((function(t,n,r){t[r?0:1].push(n)}),(function(){return[[],[]]})),Co=Xe((function(t,n){if(null==t)return[];var r=n.length;return r>1&&wu(t,n[0],n[1])?n=[]:r>2&&wu(n[0],n[1],n[2])&&(n=[n[0]]),Ve(t,be(n,1),[])})),Lo=vn||function(){return hn.Date.now()};function Oo(t,n,r){return n=r?e:n,n=t&&null==n?t.length:n,Qi(t,l,e,e,e,e,n)}function Ro(t,n){var r;if("function"!=typeof n)throw new Ot(i);return t=ga(t),function(){return--t>0&&(r=n.apply(this,arguments)),t<=1&&(n=e),r}}var Io=Xe((function(t,n,r){var e=1;if(r.length){var i=fr(r,fu(Io));e|=c}return Qi(t,e,n,r,i)})),zo=Xe((function(t,n,r){var e=3;if(r.length){var i=fr(r,fu(zo));e|=c}return Qi(n,e,t,r,i)}));function To(t,n,r){var u,o,a,c,f,l,s=0,p=!1,h=!1,v=!0;if("function"!=typeof t)throw new Ot(i);function _(n){var r=u,i=o;return u=o=e,s=n,c=t.apply(i,r)}function d(t){return s=t,f=zu(y,n),p?_(t):c}function g(t){var r=t-l;return l===e||r>=n||r<0||h&&t-s>=a}function y(){var t=Lo();if(g(t))return b(t);f=zu(y,function(t){var r=n-(t-l);return h?wr(r,a-(t-s)):r}(t))}function b(t){return f=e,v&&u?_(t):(u=o=e,c)}function m(){var t=Lo(),r=g(t);if(u=arguments,o=this,l=t,r){if(f===e)return d(l);if(h)return Ei(f),f=zu(y,n),_(l)}return f===e&&(f=zu(y,n)),c}return n=ba(n)||0,ea(r)&&(p=!!r.leading,a=(h="maxWait"in r)?mr(ba(r.maxWait)||0,n):a,v="trailing"in r?!!r.trailing:v),m.cancel=function(){f!==e&&Ei(f),s=0,u=l=o=f=e},m.flush=function(){return f===e?c:b(Lo())},m}var Do=Xe((function(t,n){return pe(t,1,n)})),Wo=Xe((function(t,n,r){return pe(t,ba(n)||0,r)}));function $o(t,n){if("function"!=typeof t||null!=n&&"function"!=typeof n)throw new Ot(i);var r=function(){var e=arguments,i=n?n.apply(this,e):e[0],u=r.cache;if(u.has(i))return u.get(i);var o=t.apply(this,e);return r.cache=u.set(i,o)||u,o};return r.cache=new($o.Cache||Kr),r}function Bo(t){if("function"!=typeof t)throw new Ot(i);return function(){var n=arguments;switch(n.length){case 0:return!t.call(this);case 1:return!t.call(this,n[0]);case 2:return!t.call(this,n[0],n[1]);case 3:return!t.call(this,n[0],n[1],n[2])}return!t.apply(this,n)}}$o.Cache=Kr;var Uo=ki((function(t,n){var r=(n=1==n.length&&Zo(n[0])?zn(n[0],Jn(lu())):zn(be(n,1),Jn(lu()))).length;return Xe((function(e){for(var i=-1,u=wr(e.length,r);++i=n})),Vo=ze(function(){return arguments}())?ze:function(t){return ia(t)&&Wt.call(t,"callee")&&!Kt.call(t,"callee")},Zo=ot.isArray,Go=bn?Jn(bn):function(t){return ia(t)&&je(t)==z};function Ko(t){return null!=t&&ra(t.length)&&!ta(t)}function Yo(t){return ia(t)&&Ko(t)}var Jo=Vn||bc,Xo=mn?Jn(mn):function(t){return ia(t)&&je(t)==m};function Qo(t){if(!ia(t))return!1;var n=je(t);return n==w||"[object DOMException]"==n||"string"==typeof t.message&&"string"==typeof t.name&&!aa(t)}function ta(t){if(!ea(t))return!1;var n=je(t);return n==k||n==x||"[object AsyncFunction]"==n||"[object Proxy]"==n}function na(t){return"number"==typeof t&&t==ga(t)}function ra(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=h}function ea(t){var n=typeof t;return null!=t&&("object"==n||"function"==n)}function ia(t){return null!=t&&"object"==typeof t}var ua=wn?Jn(wn):function(t){return ia(t)&&du(t)==E};function oa(t){return"number"==typeof t||ia(t)&&je(t)==S}function aa(t){if(!ia(t)||je(t)!=A)return!1;var n=Zt(t);if(null===n)return!0;var r=Wt.call(n,"constructor")&&n.constructor;return"function"==typeof r&&r instanceof r&&Dt.call(r)==Ht}var ca=kn?Jn(kn):function(t){return ia(t)&&je(t)==C},fa=xn?Jn(xn):function(t){return ia(t)&&du(t)==L};function la(t){return"string"==typeof t||!Zo(t)&&ia(t)&&je(t)==O}function sa(t){return"symbol"==typeof t||ia(t)&&je(t)==R}var pa=En?Jn(En):function(t){return ia(t)&&ra(t.length)&&!!on[je(t)]},ha=Gi(He),va=Gi((function(t,n){return t<=n}));function _a(t){if(!t)return[];if(Ko(t))return la(t)?hr(t):Ri(t);if(nn&&t[nn])return function(t){for(var n,r=[];!(n=t.next()).done;)r.push(n.value);return r}(t[nn]());var n=du(t);return(n==E?ar:n==L?lr:Fa)(t)}function da(t){return t?(t=ba(t))===p||t===-1/0?17976931348623157e292*(t<0?-1:1):t==t?t:0:0===t?t:0}function ga(t){var n=da(t),r=n%1;return n==n?r?n-r:n:0}function ya(t){return t?fe(ga(t),0,_):0}function ba(t){if("number"==typeof t)return t;if(sa(t))return v;if(ea(t)){var n="function"==typeof t.valueOf?t.valueOf():t;t=ea(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=Yn(t);var r=dt.test(t);return r||yt.test(t)?ln(t.slice(2),r?2:8):_t.test(t)?v:+t}function ma(t){return Ii(t,Da(t))}function wa(t){return null==t?"":si(t)}var ka=Ti((function(t,n){if(Su(n)||Ko(n))Ii(n,Ta(n),t);else for(var r in n)Wt.call(n,r)&&ee(t,r,n[r])})),xa=Ti((function(t,n){Ii(n,Da(n),t)})),Ea=Ti((function(t,n,r,e){Ii(n,Da(n),t,e)})),Sa=Ti((function(t,n,r,e){Ii(n,Ta(n),t,e)})),Aa=iu(ce),ja=Xe((function(t,n){t=jt(t);var r=-1,i=n.length,u=i>2?n[2]:e;for(u&&wu(n[0],n[1],u)&&(i=1);++r1),n})),Ii(t,ou(t),r),e&&(r=le(r,7,ru));for(var i=n.length;i--;)hi(r,n[i]);return r})),Ua=iu((function(t,n){return null==t?{}:function(t,n){return Ze(t,n,(function(n,r){return Oa(t,r)}))}(t,n)}));function Ha(t,n){if(null==t)return{};var r=zn(ou(t),(function(t){return[t]}));return n=lu(n),Ze(t,r,(function(t,r){return n(t,r[0])}))}var Ma=Xi(Ta),Pa=Xi(Da);function Fa(t){return null==t?[]:Xn(t,Ta(t))}var qa=Bi((function(t,n,r){return n=n.toLowerCase(),t+(r?Na(n):n)}));function Na(t){return Qa(wa(t).toLowerCase())}function Va(t){return(t=wa(t))&&t.replace(mt,er).replace(Xt,"")}var Za=Bi((function(t,n,r){return t+(r?"-":"")+n.toLowerCase()})),Ga=Bi((function(t,n,r){return t+(r?" ":"")+n.toLowerCase()})),Ka=$i("toLowerCase"),Ya=Bi((function(t,n,r){return t+(r?"_":"")+n.toLowerCase()})),Ja=Bi((function(t,n,r){return t+(r?" ":"")+Qa(n)})),Xa=Bi((function(t,n,r){return t+(r?" ":"")+n.toUpperCase()})),Qa=$i("toUpperCase");function tc(t,n,r){return t=wa(t),(n=r?e:n)===e?function(t){return rn.test(t)}(t)?function(t){return t.match(tn)||[]}(t):function(t){return t.match(lt)||[]}(t):t.match(n)||[]}var nc=Xe((function(t,n){try{return Sn(t,e,n)}catch(t){return Qo(t)?t:new Et(t)}})),rc=iu((function(t,n){return jn(n,(function(n){n=Uu(n),ae(t,n,Io(t[n],t))})),t}));function ec(t){return function(){return t}}var ic=Mi(),uc=Mi(!0);function oc(t){return t}function ac(t){return $e("function"==typeof t?t:le(t,1))}var cc=Xe((function(t,n){return function(r){return Ie(r,t,n)}})),fc=Xe((function(t,n){return function(r){return Ie(t,r,n)}}));function lc(t,n,r){var e=Ta(n),i=Ee(n,e);null!=r||ea(n)&&(i.length||!e.length)||(r=n,n=t,t=this,i=Ee(n,Ta(n)));var u=!(ea(r)&&"chain"in r&&!r.chain),o=ta(t);return jn(i,(function(r){var e=n[r];t[r]=e,o&&(t.prototype[r]=function(){var n=this.__chain__;if(u||n){var r=t(this.__wrapped__),i=r.__actions__=Ri(this.__actions__);return i.push({func:e,args:arguments,thisArg:t}),r.__chain__=n,r}return e.apply(t,Tn([this.value()],arguments))})})),t}function sc(){}var pc=Ni(zn),hc=Ni(Ln),vc=Ni($n);function _c(t){return ku(t)?Nn(Uu(t)):function(t){return function(n){return Se(n,t)}}(t)}var dc=Zi(),gc=Zi(!0);function yc(){return[]}function bc(){return!1}var mc,wc=qi((function(t,n){return t+n}),0),kc=Yi("ceil"),xc=qi((function(t,n){return t/n}),1),Ec=Yi("floor"),Sc=qi((function(t,n){return t*n}),1),Ac=Yi("round"),jc=qi((function(t,n){return t-n}),0);return Pr.after=function(t,n){if("function"!=typeof n)throw new Ot(i);return t=ga(t),function(){if(--t<1)return n.apply(this,arguments)}},Pr.ary=Oo,Pr.assign=ka,Pr.assignIn=xa,Pr.assignInWith=Ea,Pr.assignWith=Sa,Pr.at=Aa,Pr.before=Ro,Pr.bind=Io,Pr.bindAll=rc,Pr.bindKey=zo,Pr.castArray=function(){if(!arguments.length)return[];var t=arguments[0];return Zo(t)?t:[t]},Pr.chain=vo,Pr.chunk=function(t,n,r){n=(r?wu(t,n,r):n===e)?1:mr(ga(n),0);var i=null==t?0:t.length;if(!i||n<1)return[];for(var u=0,o=0,a=ot(gn(i/n));uu?0:u+r),(i=i===e||i>u?u:ga(i))<0&&(i+=u),i=r>i?0:ya(i);r>>0)?(t=wa(t))&&("string"==typeof n||null!=n&&!ca(n))&&!(n=si(n))&&or(t)?xi(hr(t),0,r):t.split(n,r):[]},Pr.spread=function(t,n){if("function"!=typeof t)throw new Ot(i);return n=null==n?0:mr(ga(n),0),Xe((function(r){var e=r[n],i=xi(r,0,n);return e&&Tn(i,e),Sn(t,this,i)}))},Pr.tail=function(t){var n=null==t?0:t.length;return n?ui(t,1,n):[]},Pr.take=function(t,n,r){return t&&t.length?ui(t,0,(n=r||n===e?1:ga(n))<0?0:n):[]},Pr.takeRight=function(t,n,r){var i=null==t?0:t.length;return i?ui(t,(n=i-(n=r||n===e?1:ga(n)))<0?0:n,i):[]},Pr.takeRightWhile=function(t,n){return t&&t.length?_i(t,lu(n,3),!1,!0):[]},Pr.takeWhile=function(t,n){return t&&t.length?_i(t,lu(n,3)):[]},Pr.tap=function(t,n){return n(t),t},Pr.throttle=function(t,n,r){var e=!0,u=!0;if("function"!=typeof t)throw new Ot(i);return ea(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),To(t,n,{leading:e,maxWait:n,trailing:u})},Pr.thru=_o,Pr.toArray=_a,Pr.toPairs=Ma,Pr.toPairsIn=Pa,Pr.toPath=function(t){return Zo(t)?zn(t,Uu):sa(t)?[t]:Ri(Bu(wa(t)))},Pr.toPlainObject=ma,Pr.transform=function(t,n,r){var e=Zo(t),i=e||Jo(t)||pa(t);if(n=lu(n,4),null==r){var u=t&&t.constructor;r=i?e?new u:[]:ea(t)&&ta(u)?Fr(Zt(t)):{}}return(i?jn:ke)(t,(function(t,e,i){return n(r,t,e,i)})),r},Pr.unary=function(t){return Oo(t,1)},Pr.union=eo,Pr.unionBy=io,Pr.unionWith=uo,Pr.uniq=function(t){return t&&t.length?pi(t):[]},Pr.uniqBy=function(t,n){return t&&t.length?pi(t,lu(n,2)):[]},Pr.uniqWith=function(t,n){return n="function"==typeof n?n:e,t&&t.length?pi(t,e,n):[]},Pr.unset=function(t,n){return null==t||hi(t,n)},Pr.unzip=oo,Pr.unzipWith=ao,Pr.update=function(t,n,r){return null==t?t:vi(t,n,mi(r))},Pr.updateWith=function(t,n,r,i){return i="function"==typeof i?i:e,null==t?t:vi(t,n,mi(r),i)},Pr.values=Fa,Pr.valuesIn=function(t){return null==t?[]:Xn(t,Da(t))},Pr.without=co,Pr.words=tc,Pr.wrap=function(t,n){return Ho(mi(n),t)},Pr.xor=fo,Pr.xorBy=lo,Pr.xorWith=so,Pr.zip=po,Pr.zipObject=function(t,n){return yi(t||[],n||[],ee)},Pr.zipObjectDeep=function(t,n){return yi(t||[],n||[],ni)},Pr.zipWith=ho,Pr.entries=Ma,Pr.entriesIn=Pa,Pr.extend=xa,Pr.extendWith=Ea,lc(Pr,Pr),Pr.add=wc,Pr.attempt=nc,Pr.camelCase=qa,Pr.capitalize=Na,Pr.ceil=kc,Pr.clamp=function(t,n,r){return r===e&&(r=n,n=e),r!==e&&(r=(r=ba(r))==r?r:0),n!==e&&(n=(n=ba(n))==n?n:0),fe(ba(t),n,r)},Pr.clone=function(t){return le(t,4)},Pr.cloneDeep=function(t){return le(t,5)},Pr.cloneDeepWith=function(t,n){return le(t,5,n="function"==typeof n?n:e)},Pr.cloneWith=function(t,n){return le(t,4,n="function"==typeof n?n:e)},Pr.conformsTo=function(t,n){return null==n||se(t,n,Ta(n))},Pr.deburr=Va,Pr.defaultTo=function(t,n){return null==t||t!=t?n:t},Pr.divide=xc,Pr.endsWith=function(t,n,r){t=wa(t),n=si(n);var i=t.length,u=r=r===e?i:fe(ga(r),0,i);return(r-=n.length)>=0&&t.slice(r,u)==n},Pr.eq=Fo,Pr.escape=function(t){return(t=wa(t))&&Y.test(t)?t.replace(G,ir):t},Pr.escapeRegExp=function(t){return(t=wa(t))&&it.test(t)?t.replace(et,"\\$&"):t},Pr.every=function(t,n,r){var i=Zo(t)?Ln:de;return r&&wu(t,n,r)&&(n=e),i(t,lu(n,3))},Pr.find=bo,Pr.findIndex=Nu,Pr.findKey=function(t,n){return Un(t,lu(n,3),ke)},Pr.findLast=mo,Pr.findLastIndex=Vu,Pr.findLastKey=function(t,n){return Un(t,lu(n,3),xe)},Pr.floor=Ec,Pr.forEach=wo,Pr.forEachRight=ko,Pr.forIn=function(t,n){return null==t?t:me(t,lu(n,3),Da)},Pr.forInRight=function(t,n){return null==t?t:we(t,lu(n,3),Da)},Pr.forOwn=function(t,n){return t&&ke(t,lu(n,3))},Pr.forOwnRight=function(t,n){return t&&xe(t,lu(n,3))},Pr.get=La,Pr.gt=qo,Pr.gte=No,Pr.has=function(t,n){return null!=t&&gu(t,n,Le)},Pr.hasIn=Oa,Pr.head=Gu,Pr.identity=oc,Pr.includes=function(t,n,r,e){t=Ko(t)?t:Fa(t),r=r&&!e?ga(r):0;var i=t.length;return r<0&&(r=mr(i+r,0)),la(t)?r<=i&&t.indexOf(n,r)>-1:!!i&&Mn(t,n,r)>-1},Pr.indexOf=function(t,n,r){var e=null==t?0:t.length;if(!e)return-1;var i=null==r?0:ga(r);return i<0&&(i=mr(e+i,0)),Mn(t,n,i)},Pr.inRange=function(t,n,r){return n=da(n),r===e?(r=n,n=0):r=da(r),function(t,n,r){return t>=wr(n,r)&&t=-9007199254740991&&t<=h},Pr.isSet=fa,Pr.isString=la,Pr.isSymbol=sa,Pr.isTypedArray=pa,Pr.isUndefined=function(t){return t===e},Pr.isWeakMap=function(t){return ia(t)&&du(t)==I},Pr.isWeakSet=function(t){return ia(t)&&"[object WeakSet]"==je(t)},Pr.join=function(t,n){return null==t?"":yr.call(t,n)},Pr.kebabCase=Za,Pr.last=Xu,Pr.lastIndexOf=function(t,n,r){var i=null==t?0:t.length;if(!i)return-1;var u=i;return r!==e&&(u=(u=ga(r))<0?mr(i+u,0):wr(u,i-1)),n==n?function(t,n,r){for(var e=r+1;e--;)if(t[e]===n)return e;return e}(t,n,u):Hn(t,Fn,u,!0)},Pr.lowerCase=Ga,Pr.lowerFirst=Ka,Pr.lt=ha,Pr.lte=va,Pr.max=function(t){return t&&t.length?ge(t,oc,Ce):e},Pr.maxBy=function(t,n){return t&&t.length?ge(t,lu(n,2),Ce):e},Pr.mean=function(t){return qn(t,oc)},Pr.meanBy=function(t,n){return qn(t,lu(n,2))},Pr.min=function(t){return t&&t.length?ge(t,oc,He):e},Pr.minBy=function(t,n){return t&&t.length?ge(t,lu(n,2),He):e},Pr.stubArray=yc,Pr.stubFalse=bc,Pr.stubObject=function(){return{}},Pr.stubString=function(){return""},Pr.stubTrue=function(){return!0},Pr.multiply=Sc,Pr.nth=function(t,n){return t&&t.length?Ne(t,ga(n)):e},Pr.noConflict=function(){return hn._===this&&(hn._=Mt),this},Pr.noop=sc,Pr.now=Lo,Pr.pad=function(t,n,r){t=wa(t);var e=(n=ga(n))?pr(t):0;if(!n||e>=n)return t;var i=(n-e)/2;return Vi(yn(i),r)+t+Vi(gn(i),r)},Pr.padEnd=function(t,n,r){t=wa(t);var e=(n=ga(n))?pr(t):0;return n&&en){var i=t;t=n,n=i}if(r||t%1||n%1){var u=Er();return wr(t+u*(n-t+fn("1e-"+((u+"").length-1))),n)}return Ye(t,n)},Pr.reduce=function(t,n,r){var e=Zo(t)?Dn:Zn,i=arguments.length<3;return e(t,lu(n,4),r,i,ve)},Pr.reduceRight=function(t,n,r){var e=Zo(t)?Wn:Zn,i=arguments.length<3;return e(t,lu(n,4),r,i,_e)},Pr.repeat=function(t,n,r){return n=(r?wu(t,n,r):n===e)?1:ga(n),Je(wa(t),n)},Pr.replace=function(){var t=arguments,n=wa(t[0]);return t.length<3?n:n.replace(t[1],t[2])},Pr.result=function(t,n,r){var i=-1,u=(n=wi(n,t)).length;for(u||(u=1,t=e);++ih)return[];var r=_,e=wr(t,_);n=lu(n),t-=_;for(var i=Kn(e,n);++r=o)return t;var c=r-pr(i);if(c<1)return i;var f=a?xi(a,0,c).join(""):t.slice(0,c);if(u===e)return f+i;if(a&&(c+=f.length-c),ca(u)){if(t.slice(c).search(u)){var l,s=f;for(u.global||(u=Ct(u.source,wa(vt.exec(u))+"g")),u.lastIndex=0;l=u.exec(s);)var p=l.index;f=f.slice(0,p===e?c:p)}}else if(t.indexOf(si(u),c)!=c){var h=f.lastIndexOf(u);h>-1&&(f=f.slice(0,h))}return f+i},Pr.unescape=function(t){return(t=wa(t))&&K.test(t)?t.replace(Z,_r):t},Pr.uniqueId=function(t){var n=++$t;return wa(t)+n},Pr.upperCase=Xa,Pr.upperFirst=Qa,Pr.each=wo,Pr.eachRight=ko,Pr.first=Gu,lc(Pr,(mc={},ke(Pr,(function(t,n){Wt.call(Pr.prototype,n)||(mc[n]=t)})),mc),{chain:!1}),Pr.VERSION="4.17.21",jn(["bind","bindKey","curry","curryRight","partial","partialRight"],(function(t){Pr[t].placeholder=Pr})),jn(["drop","take"],(function(t,n){Vr.prototype[t]=function(r){r=r===e?1:mr(ga(r),0);var i=this.__filtered__&&!n?new Vr(this):this.clone();return i.__filtered__?i.__takeCount__=wr(r,i.__takeCount__):i.__views__.push({size:wr(r,_),type:t+(i.__dir__<0?"Right":"")}),i},Vr.prototype[t+"Right"]=function(n){return this.reverse()[t](n).reverse()}})),jn(["filter","map","takeWhile"],(function(t,n){var r=n+1,e=1==r||3==r;Vr.prototype[t]=function(t){var n=this.clone();return n.__iteratees__.push({iteratee:lu(t,3),type:r}),n.__filtered__=n.__filtered__||e,n}})),jn(["head","last"],(function(t,n){var r="take"+(n?"Right":"");Vr.prototype[t]=function(){return this[r](1).value()[0]}})),jn(["initial","tail"],(function(t,n){var r="drop"+(n?"":"Right");Vr.prototype[t]=function(){return this.__filtered__?new Vr(this):this[r](1)}})),Vr.prototype.compact=function(){return this.filter(oc)},Vr.prototype.find=function(t){return this.filter(t).head()},Vr.prototype.findLast=function(t){return this.reverse().find(t)},Vr.prototype.invokeMap=Xe((function(t,n){return"function"==typeof t?new Vr(this):this.map((function(r){return Ie(r,t,n)}))})),Vr.prototype.reject=function(t){return this.filter(Bo(lu(t)))},Vr.prototype.slice=function(t,n){t=ga(t);var r=this;return r.__filtered__&&(t>0||n<0)?new Vr(r):(t<0?r=r.takeRight(-t):t&&(r=r.drop(t)),n!==e&&(r=(n=ga(n))<0?r.dropRight(-n):r.take(n-t)),r)},Vr.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},Vr.prototype.toArray=function(){return this.take(_)},ke(Vr.prototype,(function(t,n){var r=/^(?:filter|find|map|reject)|While$/.test(n),i=/^(?:head|last)$/.test(n),u=Pr[i?"take"+("last"==n?"Right":""):n],o=i||/^find/.test(n);u&&(Pr.prototype[n]=function(){var n=this.__wrapped__,a=i?[1]:arguments,c=n instanceof Vr,f=a[0],l=c||Zo(n),s=function(t){var n=u.apply(Pr,Tn([t],a));return i&&p?n[0]:n};l&&r&&"function"==typeof f&&1!=f.length&&(c=l=!1);var p=this.__chain__,h=!!this.__actions__.length,v=o&&!p,_=c&&!h;if(!o&&l){n=_?n:new Vr(this);var d=t.apply(n,a);return d.__actions__.push({func:_o,args:[s],thisArg:e}),new Nr(d,p)}return v&&_?t.apply(this,a):(d=this.thru(s),v?i?d.value()[0]:d.value():d)})})),jn(["pop","push","shift","sort","splice","unshift"],(function(t){var n=Rt[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",e=/^(?:pop|shift)$/.test(t);Pr.prototype[t]=function(){var t=arguments;if(e&&!this.__chain__){var i=this.value();return n.apply(Zo(i)?i:[],t)}return this[r]((function(r){return n.apply(Zo(r)?r:[],t)}))}})),ke(Vr.prototype,(function(t,n){var r=Pr[n];if(r){var e=r.name+"";Wt.call(zr,e)||(zr[e]=[]),zr[e].push({name:n,func:r})}})),zr[Pi(e,2).name]=[{name:"wrapper",func:e}],Vr.prototype.clone=function(){var t=new Vr(this.__wrapped__);return t.__actions__=Ri(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=Ri(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=Ri(this.__views__),t},Vr.prototype.reverse=function(){if(this.__filtered__){var t=new Vr(this);t.__dir__=-1,t.__filtered__=!0}else(t=this.clone()).__dir__*=-1;return t},Vr.prototype.value=function(){var t=this.__wrapped__.value(),n=this.__dir__,r=Zo(t),e=n<0,i=r?t.length:0,u=function(t,n,r){for(var e=-1,i=r.length;++e=this.__values__.length;return{done:t,value:t?e:this.__values__[this.__index__++]}},Pr.prototype.plant=function(t){for(var n,r=this;r instanceof qr;){var i=Mu(r);i.__index__=0,i.__values__=e,n?u.__wrapped__=i:n=i;var u=i;r=r.__wrapped__}return u.__wrapped__=t,n},Pr.prototype.reverse=function(){var t=this.__wrapped__;if(t instanceof Vr){var n=t;return this.__actions__.length&&(n=new Vr(this)),(n=n.reverse()).__actions__.push({func:_o,args:[ro],thisArg:e}),new Nr(n,this.__chain__)}return this.thru(ro)},Pr.prototype.toJSON=Pr.prototype.valueOf=Pr.prototype.value=function(){return di(this.__wrapped__,this.__actions__)},Pr.prototype.first=Pr.prototype.head,nn&&(Pr.prototype[nn]=function(){return this}),Pr}();_n?((_n.exports=dr)._=dr,vn._=dr):hn._=dr}.call(r);var i=function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")},u=function(){function t(t,n){for(var r=0;r1&&void 0!==arguments[1]?arguments[1]:1,r=n>0?t.toFixed(n).replace(/0+$/,"").replace(/\.$/,""):t.toString();return r||"0"}var f=function(){function t(n,r,e,u){i(this,t);var a=this;if(void 0===n);else if(Array.isArray(n))this.rgba=n;else if(void 0===e){var c=n&&""+n;c&&function(n){if(n.startsWith("hsl")){var r=n.match(/([\-\d\.e]+)/g).map(Number),e=o(r,4),i=e[0],u=e[1],c=e[2],f=e[3];void 0===f&&(f=1),i/=360,u/=100,c/=100,a.hsla=[i,u,c,f]}else if(n.startsWith("rgb")){var l=n.match(/([\-\d\.e]+)/g).map(Number),s=o(l,4),p=s[0],h=s[1],v=s[2],_=s[3];void 0===_&&(_=1),a.rgba=[p,h,v,_]}else n.startsWith("#")?a.rgba=t.hexToRgb(n):a.rgba=t.nameToRgb(n)||t.hexToRgb(n)}(c.toLowerCase())}else this.rgba=[n,r,e,void 0===u?1:u]}return u(t,[{key:"printRGB",value:function(t){var n=(t?this.rgba:this.rgba.slice(0,3)).map((function(t,n){return c(t,3===n?3:0)}));return t?"rgba("+n+")":"rgb("+n+")"}},{key:"printHSL",value:function(t){var n=[360,100,100,1],r=["","%","%",""],e=(t?this.hsla:this.hsla.slice(0,3)).map((function(t,e){return c(t*n[e],3===e?3:1)+r[e]}));return t?"hsla("+e+")":"hsl("+e+")"}},{key:"printHex",value:function(t){var n=this.hex;return t?n:n.substring(0,7)}},{key:"rgba",get:function(){if(this._rgba)return this._rgba;if(!this._hsla)throw new Error("No color is set");return this._rgba=t.hslToRgb(this._hsla)},set:function(t){3===t.length&&(t[3]=1),this._rgba=t,this._hsla=null}},{key:"rgbString",get:function(){return this.printRGB()}},{key:"rgbaString",get:function(){return this.printRGB(!0)}},{key:"hsla",get:function(){if(this._hsla)return this._hsla;if(!this._rgba)throw new Error("No color is set");return this._hsla=t.rgbToHsl(this._rgba)},set:function(t){3===t.length&&(t[3]=1),this._hsla=t,this._rgba=null}},{key:"hslString",get:function(){return this.printHSL()}},{key:"hslaString",get:function(){return this.printHSL(!0)}},{key:"hex",get:function(){return"#"+this.rgba.map((function(t,n){return n<3?t.toString(16):Math.round(255*t).toString(16)})).map((function(t){return t.padStart(2,"0")})).join("")},set:function(n){this.rgba=t.hexToRgb(n)}}],[{key:"hexToRgb",value:function(t){var n=(t.startsWith("#")?t.slice(1):t).replace(/^(\w{3})$/,"$1F").replace(/^(\w)(\w)(\w)(\w)$/,"$1$1$2$2$3$3$4$4").replace(/^(\w{6})$/,"$1FF");if(!n.match(/^([0-9a-fA-F]{8})$/))throw new Error("Unknown hex color; "+t);var r=n.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map((function(t){return parseInt(t,16)}));return r[3]=r[3]/255,r}},{key:"nameToRgb",value:function(n){var r=n.toLowerCase().replace("at","T").replace(/[aeiouyldf]/g,"").replace("ght","L").replace("rk","D").slice(-5,4),e=a[r];return void 0===e?e:t.hexToRgb(e.replace(/\-/g,"00").padStart(6,"f"))}},{key:"rgbToHsl",value:function(t){var n=o(t,4),r=n[0],e=n[1],i=n[2],u=n[3];r/=255,e/=255,i/=255;var a=Math.max(r,e,i),c=Math.min(r,e,i),f=void 0,l=void 0,s=(a+c)/2;if(a===c)f=l=0;else{var p=a-c;switch(l=s>.5?p/(2-a-c):p/(a+c),a){case r:f=(e-i)/p+(e1&&(r-=1),r<1/6?t+6*(n-t)*r:r<.5?n:r<2/3?t+(n-t)*(2/3-r)*6:t},s=i<.5?i*(1+e):i+e-i*e,p=2*i-s;a=l(p,s,r+1/3),c=l(p,s,r),f=l(p,s,r-1/3)}var h=[255*a,255*c,255*f].map(Math.round);return h[3]=u,h}}]),t}(),l=function(){function t(){i(this,t),this._events=[]}return u(t,[{key:"add",value:function(t,n,r){t.addEventListener(n,r,!1),this._events.push({target:t,type:n,handler:r})}},{key:"remove",value:function(n,r,e){this._events=this._events.filter((function(i){var u=!0;return n&&n!==i.target&&(u=!1),r&&r!==i.type&&(u=!1),e&&e!==i.handler&&(u=!1),u&&t._doRemove(i.target,i.type,i.handler),!u}))}},{key:"destroy",value:function(){this._events.forEach((function(n){return t._doRemove(n.target,n.type,n.handler)})),this._events=[]}}],[{key:"_doRemove",value:function(t,n,r){t.removeEventListener(n,r,!1)}}]),t}();function s(t,n,r){var e=!1;function i(t,n,r){return Math.max(n,Math.min(t,r))}function u(t,u,o){if(o&&(e=!0),e){t.preventDefault();var a=n.getBoundingClientRect(),c=a.width,f=a.height,l=u.clientX,s=u.clientY,p=i(l-a.left,0,c),h=i(s-a.top,0,f);r(p/c,h/f)}}function o(t,n){1===(void 0===t.buttons?t.which:t.buttons)?u(t,t,n):e=!1}function a(t,n){1===t.touches.length?u(t,t.touches[0],n):e=!1}t.add(n,"mousedown",(function(t){o(t,!0)})),t.add(n,"touchstart",(function(t){a(t,!0)})),t.add(window,"mousemove",o),t.add(n,"touchmove",a),t.add(window,"mouseup",(function(t){e=!1})),t.add(n,"touchend",(function(t){e=!1})),t.add(n,"touchcancel",(function(t){e=!1}))}var p="keydown",h="mousedown",v="focusin";function _(t,n){return(n||document).querySelector(t)}function d(t){t.preventDefault(),t.stopPropagation()}function g(t,n,r,e,i){t.add(n,p,(function(t){r.indexOf(t.key)>=0&&(i&&d(t),e(t))}))}var y=document.createElement("style");y.textContent=".picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:stretch;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:'';display:block;width:100%;height:0;-webkit-box-ordinal-group:2;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{-webkit-box-flex:1;flex:1 1 auto}.layout_default .picker_sl::before{content:'';display:block;padding-bottom:100%}.layout_default .picker_editor{-webkit-box-ordinal-group:2;order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{-webkit-box-ordinal-group:2;order:1;-webkit-box-flex:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{-webkit-box-ordinal-group:2;order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px dodgerblue}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:whitesmoke;background-image:-webkit-gradient(linear, left bottom, left top, from(gainsboro), to(transparent));background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:-webkit-gradient(linear, left bottom, left top, from(transparent), to(gainsboro));background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:white}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid white;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:-webkit-gradient(linear, left top, right top, from(red), color-stop(yellow), color-stop(lime), color-stop(cyan), color-stop(blue), color-stop(magenta), to(red));background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:-webkit-gradient(linear, left top, left bottom, from(white), color-stop(50%, rgba(255,255,255,0))),-webkit-gradient(linear, left bottom, left top, from(black), color-stop(50%, rgba(0,0,0,0))),-webkit-gradient(linear, left top, right top, from(gray), to(rgba(128,128,128,0)));background-image:linear-gradient(180deg, white, rgba(255,255,255,0) 50%),linear-gradient(0deg, black, rgba(0,0,0,0) 50%),linear-gradient(90deg, gray, rgba(128,128,128,0))}.picker_alpha,.picker_sample{position:relative;background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2'%3E%3Cpath d='M1,0H0V1H2V2H1' fill='lightgrey'/%3E%3C/svg%3E\") left top/contain white;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:'';position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,0.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:\"\";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}",document.documentElement.firstElementChild.appendChild(y);var b=function(){function t(n){i(this,t),this.settings={popup:"right",layout:"default",alpha:!0,editor:!0,editorFormat:"hex",cancelButton:!1,defaultColor:"#0cf"},this._events=new l,this.onChange=null,this.onDone=null,this.onOpen=null,this.onClose=null,this.setOptions(n)}return u(t,[{key:"setOptions",value:function(t){var n=this;if(t){var r=this.settings;if(t instanceof HTMLElement)r.parent=t;else{r.parent&&t.parent&&r.parent!==t.parent&&(this._events.remove(r.parent),this._popupInited=!1),function(t,n,r){for(var e in t)r&&r.indexOf(e)>=0||(n[e]=t[e])}(t,r),t.onChange&&(this.onChange=t.onChange),t.onDone&&(this.onDone=t.onDone),t.onOpen&&(this.onOpen=t.onOpen),t.onClose&&(this.onClose=t.onClose);var e=t.color||t.colour;e&&this._setColor(e)}var i=r.parent;if(i&&r.popup&&!this._popupInited){var u=function(t){return n.openHandler(t)};this._events.add(i,"click",u),g(this._events,i,[" ","Spacebar","Enter"],u),this._popupInited=!0}else t.parent&&!r.popup&&this.show()}}},{key:"openHandler",value:function(t){if(this.show()){t&&t.preventDefault(),this.settings.parent.style.pointerEvents="none";var n=t&&t.type===p?this._domEdit:this.domElement;setTimeout((function(){return n.focus()}),100),this.onOpen&&this.onOpen(this.colour)}}},{key:"closeHandler",value:function(t){var n=t&&t.type,r=!1;if(t)if(n===h||n===v){var e=(this.__containedEvent||0)+100;t.timeStamp>e&&(r=!0)}else d(t),r=!0;else r=!0;r&&this.hide()&&(this.settings.parent.style.pointerEvents="",n!==h&&this.settings.parent.focus(),this.onClose&&this.onClose(this.colour))}},{key:"movePopup",value:function(t,n){this.closeHandler(),this.setOptions(t),n&&this.openHandler()}},{key:"setColor",value:function(t,n){this._setColor(t,{silent:n})}},{key:"_setColor",value:function(t,n){if("string"==typeof t&&(t=t.trim()),t){n=n||{};var r=void 0;try{r=new f(t)}catch(t){if(n.failSilently)return;throw t}if(!this.settings.alpha){var e=r.hsla;e[3]=1,r.hsla=e}this.colour=this.color=r,this._setHSLA(null,null,null,null,n)}}},{key:"setColour",value:function(t,n){this.setColor(t,n)}},{key:"show",value:function(){if(!this.settings.parent)return!1;if(this.domElement){var t=this._toggleDOM(!0);return this._setPosition(),t}var n,r,e=this.settings.template||'
',i=(n=e,(r=document.createElement("div")).innerHTML=n,r.firstElementChild);return this.domElement=i,this._domH=_(".picker_hue",i),this._domSL=_(".picker_sl",i),this._domA=_(".picker_alpha",i),this._domEdit=_(".picker_editor input",i),this._domSample=_(".picker_sample",i),this._domOkay=_(".picker_done button",i),this._domCancel=_(".picker_cancel button",i),i.classList.add("layout_"+this.settings.layout),this.settings.alpha||i.classList.add("no_alpha"),this.settings.editor||i.classList.add("no_editor"),this.settings.cancelButton||i.classList.add("no_cancel"),this._ifPopup((function(){return i.classList.add("popup")})),this._setPosition(),this.colour?this._updateUI():this._setColor(this.settings.defaultColor),this._bindEvents(),!0}},{key:"hide",value:function(){return this._toggleDOM(!1)}},{key:"destroy",value:function(){this._events.destroy(),this.domElement&&this.settings.parent.removeChild(this.domElement)}},{key:"_bindEvents",value:function(){var t=this,n=this,r=this.domElement,e=this._events;function i(t,n,r){e.add(t,n,r)}i(r,"click",(function(t){return t.preventDefault()})),s(e,this._domH,(function(t,r){return n._setHSLA(t)})),s(e,this._domSL,(function(t,r){return n._setHSLA(null,t,1-r)})),this.settings.alpha&&s(e,this._domA,(function(t,r){return n._setHSLA(null,null,null,1-r)}));var u=this._domEdit;i(u,"input",(function(t){n._setColor(this.value,{fromEditor:!0,failSilently:!0})})),i(u,"focus",(function(t){var n=this;n.selectionStart===n.selectionEnd&&n.select()})),this._ifPopup((function(){var n=function(n){return t.closeHandler(n)};i(window,h,n),i(window,v,n),g(e,r,["Esc","Escape"],n);var u=function(n){t.__containedEvent=n.timeStamp};i(r,h,u),i(r,v,u),i(t._domCancel,"click",n)}));var o=function(n){t._ifPopup((function(){return t.closeHandler(n)})),t.onDone&&t.onDone(t.colour)};i(this._domOkay,"click",o),g(e,r,["Enter"],o)}},{key:"_setPosition",value:function(){var t=this.settings.parent,n=this.domElement;t!==n.parentNode&&t.appendChild(n),this._ifPopup((function(r){"static"===getComputedStyle(t).position&&(t.style.position="relative");var e=!0===r?"popup_right":"popup_"+r;["popup_top","popup_bottom","popup_left","popup_right"].forEach((function(t){t===e?n.classList.add(t):n.classList.remove(t)})),n.classList.add(e)}))}},{key:"_setHSLA",value:function(t,n,r,e,i){i=i||{};var u=this.colour,o=u.hsla;[t,n,r,e].forEach((function(t,n){(t||0===t)&&(o[n]=t)})),u.hsla=o,this._updateUI(i),this.onChange&&!i.silent&&this.onChange(u)}},{key:"_updateUI",value:function(t){if(this.domElement){t=t||{};var n=this.colour,r=n.hsla,e="hsl("+360*r[0]+", 100%, 50%)",i=n.hslString,u=n.hslaString,o=this._domH,a=this._domSL,c=this._domA,f=_(".picker_selector",o),l=_(".picker_selector",a),s=_(".picker_selector",c);b(0,f,r[0]),this._domSL.style.backgroundColor=this._domH.style.color=e,b(0,l,r[1]),m(0,l,1-r[2]),a.style.color=i,m(0,s,1-r[3]);var p=i,h=p.replace("hsl","hsla").replace(")",", 0)"),v="linear-gradient("+[p,h]+")";if(this._domA.style.backgroundImage=v+", url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='2' height='2'%3E%3Cpath d='M1,0H0V1H2V2H1' fill='lightgrey'/%3E%3C/svg%3E\")",!t.fromEditor){var d=this.settings.editorFormat,g=this.settings.alpha,y=void 0;switch(d){case"rgb":y=n.printRGB(g);break;case"hsl":y=n.printHSL(g);break;default:y=n.printHex(g)}this._domEdit.value=y}this._domSample.style.color=u}function b(t,n,r){n.style.left=100*r+"%"}function m(t,n,r){n.style.top=100*r+"%"}}},{key:"_ifPopup",value:function(t,n){this.settings.parent&&this.settings.popup?t&&t(this.settings.popup):n&&n()}},{key:"_toggleDOM",value:function(t){var n=this.domElement;if(!n)return!1;var r=t?"":"none",e=n.style.display!==r;return e&&(n.style.display=r),e}}],[{key:"StyleElement",get:function(){return y}}]),t}();const m={hex:t=>t.hex.slice(0,7),hexa:t=>t.hex,rgb:t=>t.rgbString,rgba:t=>t.rgbaString,hsl:t=>t.hslString,hsla:t=>t.hslaString};window.FilamentColorPicker={make:function(t,n){var r;const{parent:i,editorFormat:u,popupPosition:o,alpha:a,layout:c,cancelButton:f,statePath:l,template:s,debounceTimeout:p,preview:h,nullable:v}=n,_=i.querySelector("input[data-color-picker-field]");if(!_)throw new Error("Could not find a color picker input to bind to");const d=new Proxy({value:t.get(l)},{set:(t,n,r)=>(t[n]=r,y(l,r),w(null!=r?r:"#00000000"),_.value=null!=r?r:"",!0)}),g=function(t,n){return m[n?`${t}a`:t]}(u,a),y=function(t,n){let r=(n,r)=>{t.set(n,r)};return n>0&&(r=e.exports.debounce(r,n)),r}(t,null===o?p:0),w=(k=h,x=i.querySelector("[data-preview]"),k&&x?t=>{x.style.background=t}:()=>{});var k,x;return v&&function(t,n){if(t){const r=t=>(t.preventDefault(),t.stopPropagation(),n.value=null,!1);t.addEventListener("click",r)}console.warn("Could not find clear button to bind to")}(i.querySelector('[data-color-picker-action="clear"]'),d),new b({parent:i,editorFormat:u,popup:o||!1,alpha:a,layout:c,cancelButton:f,template:s,color:null!==(r=d.value)&&void 0!==r?r:"#00000000",onChange:t=>{const n=g(t);_.value=n,w(n),null===o&&(d.value=n)},onClose:t=>{d.value=g(t)}})}},window.dispatchEvent(new CustomEvent("filament-color-picker:init"))}(); 11 | -------------------------------------------------------------------------------- /resources/js/colorpicker.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import '../css/colorpicker.css'; 3 | 4 | import { debounce } from 'lodash'; 5 | import Picker from 'vanilla-picker'; 6 | import type { EditorFormat } from 'vanilla-picker'; 7 | 8 | const formatters: Formatters = { 9 | hex: color => color.hex.slice(0, 7), 10 | hexa: color => color.hex, 11 | rgb: color => color.rgbString, 12 | rgba: color => color.rgbaString, 13 | hsl: color => color.hslString, 14 | hsla: color => color.hslaString, 15 | }; 16 | 17 | function getFormatter(editorFormat: EditorFormat, alpha: boolean): FormatterFunction { 18 | const key: FormatterKey = alpha ? `${editorFormat}a` : editorFormat; 19 | 20 | return formatters[key]; 21 | } 22 | 23 | function createPreviewUpdated(shouldPreview: boolean, previewElement: HTMLElement | null): UpdatePreviewFunction { 24 | if (!shouldPreview || !previewElement) { 25 | return () => { 26 | // noop 27 | }; 28 | } 29 | 30 | return (color: string) => { 31 | previewElement!.style.background = color; 32 | }; 33 | } 34 | 35 | function createUpdater($wire: LivewireProxy, debounceTime: number): UpdateColorFunction { 36 | let updater: UpdateColorFunction = (statePath, color) => { 37 | $wire.set(statePath, color); 38 | }; 39 | 40 | if (debounceTime > 0) { 41 | updater = debounce(updater, debounceTime); 42 | } 43 | 44 | return updater; 45 | } 46 | 47 | function initializeClear(clearButton: HTMLButtonElement | null, pickerColor: ColorProxy): void { 48 | if (clearButton) { 49 | const clearInput = (e: MouseEvent) => { 50 | e.preventDefault(); 51 | e.stopPropagation(); 52 | 53 | pickerColor.value = null; 54 | 55 | return false; 56 | }; 57 | 58 | clearButton.addEventListener('click', clearInput); 59 | } 60 | 61 | console.warn('Could not find clear button to bind to'); 62 | } 63 | 64 | function make($wire: LivewireProxy, options: ExtendedOptions): Picker { 65 | const { parent, editorFormat, popupPosition, alpha, layout, cancelButton, statePath, template, debounceTimeout, preview, nullable } = options; 66 | 67 | const colorPickerInput = parent.querySelector('input[data-color-picker-field]'); 68 | 69 | if (!colorPickerInput) { 70 | throw new Error('Could not find a color picker input to bind to'); 71 | } 72 | 73 | const pickerColor = new Proxy({ 74 | value: $wire.get(statePath), 75 | }, { 76 | set(target, property: keyof ColorProxy, value: string | null) { 77 | target[property] = value; 78 | 79 | updateLivewireProperty(statePath, value); 80 | updatePreview(value ?? '#00000000'); 81 | colorPickerInput.value = value ?? ''; 82 | 83 | return true; 84 | }, 85 | }); 86 | 87 | const formatColor = getFormatter(editorFormat!, alpha!); 88 | 89 | const updateLivewireProperty = createUpdater( 90 | $wire, 91 | null === popupPosition ? debounceTimeout : 0, 92 | ); 93 | 94 | const updatePreview = createPreviewUpdated( 95 | preview, 96 | parent.querySelector('[data-preview]'), 97 | ); 98 | 99 | if (nullable) { 100 | initializeClear( 101 | parent.querySelector('[data-color-picker-action="clear"]'), 102 | pickerColor, 103 | ); 104 | } 105 | 106 | return new Picker({ 107 | parent, 108 | editorFormat, 109 | popup: popupPosition || false, 110 | alpha, 111 | layout, 112 | cancelButton, 113 | template, 114 | color: pickerColor.value ?? '#00000000', 115 | onChange: color => { 116 | const newColor = formatColor(color); 117 | colorPickerInput.value = newColor; 118 | 119 | updatePreview(newColor); 120 | 121 | if (null === popupPosition) { 122 | pickerColor.value = newColor; 123 | } 124 | }, 125 | onClose: color => { 126 | pickerColor.value = formatColor(color); 127 | }, 128 | }); 129 | } 130 | 131 | window.FilamentColorPicker = { 132 | make, 133 | }; 134 | 135 | window.dispatchEvent(new CustomEvent('filament-color-picker:init')); 136 | -------------------------------------------------------------------------------- /resources/lang/en/swatch.php: -------------------------------------------------------------------------------- 1 | 'Copied!', 7 | ]; 8 | -------------------------------------------------------------------------------- /resources/types/colorpicker.d.ts: -------------------------------------------------------------------------------- 1 | import Picker, { Color, Options, EditorFormat } from 'vanilla-picker'; 2 | 3 | // Re-exports so they can be imported 4 | declare module 'vanilla-picker' { 5 | export interface Color { 6 | rgba: number[]; 7 | hsla: number[]; 8 | rgbString: string; 9 | rgbaString: string; 10 | hslString: string; 11 | hslaString: string; 12 | hex: string; 13 | } 14 | 15 | export type ColorCallback = (color: Color) => void; 16 | 17 | export type EditorFormat = 'hex' | 'hsl' | 'rgb'; 18 | 19 | export interface Options { 20 | parent?: HTMLElement; 21 | popup?: 'top' | 'bottom' | 'left' | 'right' | false; 22 | template?: string; 23 | layout?: string; 24 | alpha?: boolean; 25 | editor?: boolean; 26 | editorFormat?: EditorFormat; 27 | cancelButton?: boolean; 28 | color?: string; 29 | onChange?: ColorCallback; 30 | onDone?: ColorCallback; 31 | onOpen?: ColorCallback; 32 | onClose?: ColorCallback; 33 | } 34 | 35 | export type Configuration = Options | HTMLElement; 36 | } 37 | 38 | declare global { 39 | type LivewireProxy = { 40 | set(property: string, value: T): void; 41 | get(property: string): T; 42 | }; 43 | 44 | type ColorPickerMakeFunction = ($wire: LivewireProxy, options: ExtendedOptions, initialValue: any) => Picker; 45 | 46 | type FormatterKey = `${EditorFormat}a` | EditorFormat; 47 | type FormatterFunction = (color: Color) => string; 48 | type Formatters = Record; 49 | 50 | type ExtendedOptions = Options & { 51 | parent: HTMLElement, 52 | popupPosition: 'top' | 'right' | 'bottom' | 'left' | null; 53 | alpha: boolean; 54 | statePath: string; 55 | template: string | null; 56 | debounceTimeout: number; 57 | preview: boolean; 58 | nullable: boolean; 59 | }; 60 | 61 | type UpdatePreviewFunction = (color: string) => void; 62 | type UpdateColorFunction = (statePath: string, color: ColorValue) => void; 63 | 64 | type ColorValue = string | null; 65 | 66 | type ColorProxy = { 67 | value: ColorValue; 68 | }; 69 | 70 | interface Window { 71 | FilamentColorPicker: { 72 | make: ColorPickerMakeFunction; 73 | }; 74 | } 75 | } 76 | 77 | export {} 78 | -------------------------------------------------------------------------------- /resources/views/break.blade.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/views/clear-button.blade.php: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /resources/views/color-swatch.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $copyable = $isCopyable(); 3 | $tag = $copyable ? 'button' : 'div'; 4 | @endphp 5 | 6 | @if ($getState()) 7 | @if ($copyable) 8 | 41 | @endif 42 | @else 43 |   44 | @endif 45 | -------------------------------------------------------------------------------- /resources/views/colorpicker.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $popupEnabled = $isPopupEnabled(); 3 | $nullable = $isNullable(); 4 | @endphp 5 | 6 | 15 |
48 |
$popupEnabled, 53 | 'relative' => $nullable, 54 | ]) 55 | > 56 | @includeWhen($getPreview(), 'filament-colorpicker::preview') 57 | 58 | class([ 63 | 'color-picker-input', 64 | 'block transition duration-75 border border-gray-300 focus:border-primary-600 focus:ring-1 focus:ring-inset focus:ring-primary-600 disabled:opacity-70', 65 | 'dark:bg-gray-700 dark:text-white' => config('forms.dark_mode'), 66 | 'border-gray-300' => !$errors->has($getStatePath()), 67 | 'dark:border-gray-600' => !$errors->has($getStatePath()) && config('forms.dark_mode'), 68 | 'border-danger-600 ring-danger-600' => $errors->has($getStatePath()), 69 | '!rvx-rounded-r-lg flex-1 border-l-0' => $getPreview(), 70 | 'rounded-lg w-full' => !$getPreview(), 71 | ]) 72 | }} 73 | style="{{ $popupEnabled ? '' : 'margin-bottom: 0.75rem' }}" 74 | readonly="{{ $popupEnabled ? '' : 'readonly' }}" 75 | data-color-picker-field 76 | /> 77 | 78 | @includeWhen($nullable, 'filament-colorpicker::clear-button') 79 | 80 | @includeUnless($popupEnabled, 'filament-colorpicker::break') 81 |
82 |
83 |
84 | -------------------------------------------------------------------------------- /resources/views/preview.blade.php: -------------------------------------------------------------------------------- 1 |
4 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /resources/views/template.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | 8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 | 16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjs from '@rollup/plugin-commonjs'; 2 | import { nodeResolve } from '@rollup/plugin-node-resolve'; 3 | import { terser } from 'rollup-plugin-terser'; 4 | import postcss from 'rollup-plugin-postcss'; 5 | import { resolve } from 'path'; 6 | import autoprefixer from 'autoprefixer'; 7 | import tailwindcss from 'tailwindcss'; 8 | import typescript from '@rollup/plugin-typescript'; 9 | 10 | const inProduction = process.env.BUILD === 'production'; 11 | 12 | export default { 13 | input: 'resources/js/colorpicker.ts', 14 | output: { 15 | file: 'resources/dist/filament-colorpicker.js', 16 | format: 'iife', 17 | }, 18 | plugins: [ 19 | nodeResolve(), 20 | commonjs(), 21 | inProduction && terser(), 22 | postcss({ 23 | plugins: [ 24 | autoprefixer(), 25 | tailwindcss(), 26 | ], 27 | extract: resolve(__dirname, 'resources', 'dist', 'filament-colorpicker.css'), 28 | minimize: inProduction, 29 | }), 30 | typescript(), 31 | ], 32 | }; 33 | -------------------------------------------------------------------------------- /src/Columns/ColorSwatch.php: -------------------------------------------------------------------------------- 1 | copyable = true; 22 | 23 | return $this; 24 | } 25 | 26 | public function copyMessage(string $message): self 27 | { 28 | $this->copyMessage = $message; 29 | 30 | return $this; 31 | } 32 | 33 | public function getCopyMessage(): string 34 | { 35 | return $this->copyMessage ?? trans('filament-colorpicker::swatch.copied_message'); 36 | } 37 | 38 | public function copyMessageShowTimeMs(int $timeInMs): self 39 | { 40 | $this->copyMessageShowTimeMs = $timeInMs; 41 | 42 | return $this; 43 | } 44 | 45 | public function getCopyMessageShowTimeMs(): int 46 | { 47 | return $this->copyMessageShowTimeMs; 48 | } 49 | 50 | public function isCopyable(): bool 51 | { 52 | return $this->copyable; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Enum/ColorPattern.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/../resources/dist/filament-colorpicker.js', 19 | ]; 20 | 21 | /** 22 | * @var string[] 23 | */ 24 | protected array $styles = [ 25 | 'rvxlab-filament-colorpicker' => __DIR__ . '/../resources/dist/filament-colorpicker.css', 26 | ]; 27 | 28 | public function configurePackage(Package $package): void 29 | { 30 | $package 31 | ->name('filament-colorpicker') 32 | ->hasViews() 33 | ->hasTranslations(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Forms/ColorPicker.php: -------------------------------------------------------------------------------- 1 | initialize(); 40 | } 41 | 42 | public function initialize(): void 43 | { 44 | $this->editorFormat = EditorFormat::HEX(); 45 | $this->popupPosition = PopupPosition::RIGHT(); 46 | 47 | $this->afterStateHydrated(function (self $component, ?string $state): void { 48 | $component->state($state); 49 | }); 50 | 51 | $this->rule(function (self $component) { 52 | return "regex:{$component->determineColorPattern()}"; 53 | }); 54 | } 55 | 56 | public function editorFormat(EditorFormat|string $editorFormat): static 57 | { 58 | $this->editorFormat = new EditorFormat($editorFormat); 59 | 60 | return $this; 61 | } 62 | 63 | public function getEditorFormat(): EditorFormat 64 | { 65 | return $this->editorFormat; 66 | } 67 | 68 | public function popupPosition(PopupPosition|string $popupPosition): static 69 | { 70 | $this->popupPosition = new PopupPosition($popupPosition); 71 | 72 | return $this; 73 | } 74 | 75 | public function getPopupPosition(): ?PopupPosition 76 | { 77 | return $this->popupPosition; 78 | } 79 | 80 | public function disablePopup(): static 81 | { 82 | $this->popupPosition = null; 83 | 84 | return $this; 85 | } 86 | 87 | public function isPopupEnabled(): bool 88 | { 89 | return $this->popupPosition !== null; 90 | } 91 | 92 | public function alpha(bool $useAlphaChannel): static 93 | { 94 | $this->alpha = $useAlphaChannel; 95 | 96 | return $this; 97 | } 98 | 99 | public function getAlpha(): bool 100 | { 101 | return $this->alpha; 102 | } 103 | 104 | public function preview(bool $showPreview = true): static 105 | { 106 | $this->preview = $showPreview; 107 | 108 | return $this; 109 | } 110 | 111 | public function getPreview(): bool 112 | { 113 | return $this->preview; 114 | } 115 | 116 | public function layout(string $layout): static 117 | { 118 | $this->layout = $layout; 119 | 120 | return $this; 121 | } 122 | 123 | public function getLayout(): string 124 | { 125 | return $this->layout; 126 | } 127 | 128 | public function cancelButton(bool $showCancelButton): static 129 | { 130 | $this->cancelButton = $showCancelButton; 131 | 132 | return $this; 133 | } 134 | 135 | public function getCancelButton(): bool 136 | { 137 | return $this->cancelButton; 138 | } 139 | 140 | public function template(View | string $template): static 141 | { 142 | if ($template instanceof View) { 143 | $this->colorPickerTemplate = $template->render(); 144 | } else { 145 | $this->colorPickerTemplate = $template; 146 | } 147 | 148 | return $this; 149 | } 150 | 151 | public function getTemplate(): ?string 152 | { 153 | return $this->colorPickerTemplate; 154 | } 155 | 156 | public function debounceTimeout(int $timeout): static 157 | { 158 | $this->debounceTimeout = $timeout; 159 | 160 | return $this; 161 | } 162 | 163 | public function getDebounceTimeout(): int 164 | { 165 | return $this->debounceTimeout; 166 | } 167 | 168 | public function nullable(\Closure|bool $condition = true): static 169 | { 170 | parent::nullable($condition); 171 | 172 | $this->nullable = $this->evaluate($condition); 173 | 174 | return $this; 175 | } 176 | 177 | public function isNullable(): bool 178 | { 179 | return $this->nullable; 180 | } 181 | 182 | /** 183 | * @return array{editorFormat: string, popupPosition: ?string, alpha: bool, layout: string, cancelButton: bool, statePath: string, template: ?string, debounceTimeout: int, preview: bool} 184 | */ 185 | public function getPickerOptions(): array 186 | { 187 | /** @var string|null $popupPosition */ 188 | $popupPosition = $this->getPopupPosition()?->getValue(); 189 | 190 | return [ 191 | 'editorFormat' => (string) $this->getEditorFormat(), 192 | 'popupPosition' => $popupPosition, 193 | 'alpha' => $this->getAlpha(), 194 | 'layout' => $this->getLayout(), 195 | 'cancelButton' => $this->getCancelButton(), 196 | 'statePath' => $this->getStatePath(), 197 | 'template' => $this->getTemplate(), 198 | 'debounceTimeout' => $this->getDebounceTimeout(), 199 | 'preview' => $this->getPreview(), 200 | 'nullable' => $this->isNullable(), 201 | ]; 202 | } 203 | 204 | protected function determineColorPattern(): string 205 | { 206 | if ($this->alpha) { 207 | return match ($this->editorFormat->getValue()) { 208 | EditorFormat::RGB => ColorPattern::RGBA, 209 | EditorFormat::HSL => ColorPattern::HSLA, 210 | default => ColorPattern::HEXA, 211 | }; 212 | } 213 | 214 | return match ($this->editorFormat->getValue()) { 215 | EditorFormat::RGB => ColorPattern::RGB, 216 | EditorFormat::HSL => ColorPattern::HSL, 217 | default => ColorPattern::HEX, 218 | }; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | prefix: 'rvx-', 3 | content: [ 4 | './resources/views/**/*.blade.php', 5 | ], 6 | safelist: [ 7 | 'picker_wrapper', 8 | ], 9 | theme: { 10 | extend: {}, 11 | }, 12 | plugins: [], 13 | }; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "lib": [ 5 | "DOM", 6 | "ESNext" 7 | ], 8 | "module": "ESNext", 9 | "rootDir": "resources/js", 10 | "esModuleInterop": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "strict": true, 13 | "skipLibCheck": true, 14 | "typeRoots": [ 15 | "./node_modules/@types", 16 | "./resources/types" 17 | ], 18 | "moduleResolution": "node", 19 | }, 20 | "include": [ 21 | "resources/js", 22 | "resources/types" 23 | ], 24 | "exclude": [ 25 | "node_modules", 26 | "rollup.config.js" 27 | ] 28 | } 29 | --------------------------------------------------------------------------------