├── .github └── workflows │ └── test.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── Appraisals ├── Gemfile ├── README.md ├── Rakefile ├── bin └── ruby_csso ├── csso-rails.gemspec ├── gemfiles ├── rails_5.gemfile ├── rails_6.gemfile ├── sprockets_2.gemfile ├── sprockets_3.gemfile └── sprockets_4.gemfile ├── lib ├── csso-rails.rb ├── csso.rb └── csso │ ├── cli.rb │ ├── compressor.rb │ ├── csso.js.erb │ ├── js_lib.rb │ ├── railtie.rb │ └── version.rb ├── spec ├── csso │ ├── csso_spec.rb │ └── sprockets_integration_spec.rb └── fixtures │ ├── app │ └── assets │ │ └── config │ │ └── manifest.js │ ├── test.css │ ├── test2.css │ ├── test3.scss │ └── test4.scss └── vendor └── csso └── csso.js /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push] 3 | jobs: 4 | runTests: 5 | runs-on: ubuntu-latest 6 | 7 | strategy: 8 | matrix: 9 | ruby-version: [2.7.7, 3.1.3] # , 3.0.5, 3.1.3] 10 | appraisal: 11 | - sprockets_2 12 | - sprockets_3 13 | - sprockets_4 14 | - rails_5 15 | - rails_6 16 | 17 | env: 18 | BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.appraisal }}.gemfile 19 | 20 | steps: 21 | - uses: actions/checkout@master 22 | - name: Install ruby 23 | uses: ruby/setup-ruby@v1 24 | with: 25 | ruby-version: ${{ matrix.ruby-version }} 26 | bundler-cache: true 27 | 28 | - name: Run tests 29 | run: | 30 | bundle exec rake spec 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *~ 3 | 4 | pkg/ 5 | .yardoc/ 6 | 7 | .rvmrc 8 | .bundle 9 | tmp 10 | /csso/ 11 | /log/ 12 | /.idea/ 13 | 14 | Gemfile.lock 15 | gemfiles/*.lock 16 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # The behavior of RuboCop can be controlled via the .rubocop.yml 2 | # configuration file. It makes it possible to enable/disable 3 | # certain cops (checks) and to alter their behavior if they accept 4 | # any parameters. The file can be placed either in your home 5 | # directory or in some project directory. 6 | # 7 | # RuboCop will start looking for the configuration file in the directory 8 | # where the inspected file is and continue its way up to the root directory. 9 | # 10 | # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md 11 | 12 | require: 13 | - 'rubocop-performance' 14 | - 'rubocop-minitest' 15 | - 'rubocop-rake' 16 | 17 | AllCops: 18 | # DefaultFormatter: fuubar 19 | 20 | # modern rubocop dropped old rubies, use oldest available 21 | TargetRubyVersion: 2.5 22 | NewCops: enable 23 | Exclude: 24 | - 'tmp/**/**' 25 | - 'csso/**' 26 | - 'pkg/**' 27 | # appraisal generates with some offences: 28 | - 'gemfiles/**' 29 | 30 | Naming/FileName: 31 | Exclude: 32 | # this is the gem name: 33 | - 'lib/csso-rails.rb' 34 | 35 | Style/NumericPredicate: 36 | # not supported in ruby < 2.3 37 | Enabled: false 38 | 39 | Style/OptionalBooleanParameter: 40 | Enabled: false 41 | 42 | Layout/LineLength: 43 | Max: 140 44 | 45 | Metrics/MethodLength: 46 | Max: 30 47 | 48 | Metrics/BlockLength: 49 | Exclude: 50 | - 'spec/**/**' 51 | - '*.gemspec' 52 | 53 | Metrics/AbcSize: 54 | Exclude: 55 | - 'lib/csso/cli.rb' -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # to test against all, run: appraisal rake spec 4 | 5 | # sprockets-1 is unsupported 6 | 7 | appraise 'sprockets-2' do 8 | gem 'sprockets', '~>2.0' 9 | end 10 | 11 | appraise 'sprockets-3' do 12 | gem 'sprockets', '~>3.0' 13 | end 14 | 15 | appraise 'sprockets-4' do 16 | gem 'sprockets', '~>4.0' 17 | gem 'sass-rails', '>=6.0' 18 | end 19 | 20 | appraise 'rails-5' do 21 | gem 'rails', '~>5.2' 22 | end 23 | 24 | appraise 'rails-6' do 25 | gem 'rails', '~>6.0.1' 26 | end 27 | 28 | # appraise "therubyracer" do 29 | # TODO: currently rubyracer segfaults on my machine, fix that and start testing 30 | # gem "therubyracer" 31 | # end 32 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | unless defined?(Appraisal) 6 | group :rubocop do 7 | gem 'rubocop' 8 | gem 'rubocop-minitest' 9 | gem 'rubocop-performance' 10 | gem 'rubocop-rake' 11 | end 12 | end 13 | 14 | gemspec 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # csso-rails: Stylesheet Optimizer (CSSO) for Rails Asset pipeline 2 | 3 | [![Gem Version](https://badge.fury.io/rb/csso-rails.svg)](https://badge.fury.io/rb/csso-rails) 4 | ![CI Status](https://github.com/Vasfed/csso-rails/actions/workflows/test.yml/badge.svg) 5 | 6 | Ruby adapter for [github.com/css/csso](https://github.com/css/csso). 7 | 8 | CSSO does structure-optimization for CSS. 9 | CSS is usually reduced more than in half in uncompressed and around 15% in gzipped. 10 | 11 | ### A Real-World Example 12 | A living rails application CSS – some written in less, some handwritten): 13 | 14 | | | Original | sass | yui 2.4.7 | csso | % of original 15 | |:-------|:------------:|:------:|:-----:|:-----:|:------: 16 | |Plain | 129497 | 107006 | 60758 | 60874 | 47% 17 | |GZipped | 14046 | 12047 | 10558 | 10472 | 74% 18 | 19 | Very close to yui compressor, wining in gzipped (you’re using nginx `mod\_gzip_static`, don’t you?) 20 | 21 | A more hard example – twitter bootstrap.css, already minified: 22 | 23 | | | Original | lessc | yui 2.4.7 | csso | % of original 24 | |:-------|:------------:|:-----:|:-----:|:-----:|:------: 25 | |Plain | 81443 | 71520 | 68755 | 67679 | 83% 26 | |GZipped | 12384 | 11633 | 11652 | 11477 | 92% 27 | 28 | Please note than benchmark was taken in summer of 2012, since then things may have changed. 29 | 30 | ## Usage 31 | 32 | ### In Rails 3.1+ 33 | 34 | Add `gem 'csso-rails'` to your gemfile, and that’s it! 35 | (also you may want to add some javascript runtime for ExecJS to pick up, like `gem 'therubyracer'`) 36 | 37 | Upon including it becomes the default compressor even if sass is included too. 38 | More explicit way – set in `config/environment/production.rb`: 39 | 40 | ```ruby 41 | config.assets.css_compressor = :csso 42 | ``` 43 | 44 | ### Sprockets 45 | 46 | If you use Sprockets without Rails: 47 | 48 | ```ruby 49 | require 'csso' 50 | Csso.install(sprockets_env) 51 | ``` 52 | 53 | ### In Plain Ruby 54 | 55 | ```ruby 56 | require 'csso' 57 | puts Csso.optimize("a{ color: #FF0000; }") # produces "a{color:red}" 58 | ``` 59 | 60 | In _maniac mode_ (`Csso.optimize(css, true)`, default for pipeline) CSS is processed several times until it stops getting lighter (there're cases when original csso does not do all optimizations for no reason). 61 | 62 | ### In Command Line 63 | 64 | ruby_csso non_optimized.css > optimized.css 65 | 66 | 67 | ## MIT-License 68 | 69 | > Original CSSO code - Copyright (C) 2011 by Sergey Kryzhanovsky. 70 | > 71 | > ruby gem - Copyright(C) 2012 Vasily Fedoseyev 72 | 73 | Permission is hereby granted, free of charge, to any person obtaining a copy 74 | of this software and associated documentation files (the "Software"), to deal 75 | in the Software without restriction, including without limitation the rights 76 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 77 | copies of the Software, and to permit persons to whom the Software is 78 | furnished to do so, subject to the following conditions: 79 | 80 | The above copyright notice and this permission notice shall be included in 81 | all copies or substantial portions of the Software. 82 | 83 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 84 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 85 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 86 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 87 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 88 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 89 | THE SOFTWARE. 90 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler' 4 | require 'bundler/setup' 5 | 6 | require 'rake/testtask' 7 | 8 | Rake::TestTask.new(:spec) do |t| 9 | t.pattern = 'spec/**/*_spec.rb' 10 | t.libs.push 'spec' 11 | end 12 | 13 | $LOAD_PATH.push File.expand_path('lib', __dir__) 14 | require 'csso/version' 15 | 16 | Bundler::GemHelper.install_tasks 17 | 18 | desc 'test is the default' 19 | task test: :spec 20 | task default: :spec 21 | 22 | file 'csso' do 23 | puts 'Fetching csso repo...' 24 | `git clone --single-branch --depth 1 --no-hardlinks https://github.com/css/csso.git` 25 | Dir.chdir('csso') do 26 | puts 'Now making web-version, just in case.' 27 | `npm install && npm run build` 28 | end 29 | end 30 | 31 | desc 'updates csso repo' 32 | task update_csso_repo: :csso do 33 | # ?? 34 | Dir.chdir('csso') do 35 | puts 'Updating csso...' 36 | `git reset --hard && git pull --rebase` 37 | `npm install && npm run build` 38 | end 39 | end 40 | 41 | directory 'vendor/csso' 42 | lib_template = 'lib/csso/csso.js.erb' 43 | file Csso::CSSO_JS_LIB => [ 44 | lib_template, 45 | 'csso', 46 | 'vendor/csso', 47 | 'csso/.git/HEAD', 48 | 'csso/.git/refs/heads/master' 49 | ] do 50 | puts "Generating #{Csso::CSSO_JS_LIB}" 51 | `erb #{lib_template} > #{Csso::CSSO_JS_LIB}` 52 | end 53 | 54 | desc 'Generate bundled csso from repo' 55 | task generate_files: [:csso, Csso::CSSO_JS_LIB] 56 | 57 | desc 'Clean generated files' 58 | task :rm_generated do 59 | puts "Removing #{Csso::CSSO_JS_LIB}" 60 | `rm #{Csso::CSSO_JS_LIB}` 61 | end 62 | 63 | task regenerate: %i[rm_generated generate_files] 64 | 65 | desc 'Update CSSO' 66 | task update_csso: %i[rm_generated update_csso_repo generate_files] 67 | 68 | desc 'alias for generate_files' 69 | task build: :generate_files 70 | -------------------------------------------------------------------------------- /bin/ruby_csso: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require 'csso-rails' 5 | require 'csso/cli' 6 | 7 | Csso::CLI.run! 8 | -------------------------------------------------------------------------------- /csso-rails.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | $LOAD_PATH.push File.expand_path('lib', __dir__) 4 | require 'csso/version' 5 | 6 | Gem::Specification.new do |s| 7 | s.name = 'csso-rails' 8 | s.version = Csso::VERSION 9 | s.platform = Gem::Platform::RUBY 10 | s.authors = ['Vasily Fedoseyev'] 11 | s.email = ['vasilyfedoseyev@gmail.com'] 12 | s.homepage = 'https://github.com/Vasfed/csso-rails' 13 | s.summary = 'CSS Stylesheet optimizer/compressor for Rails' 14 | s.description = 'Invoke the CSSO from Ruby' 15 | s.license = 'MIT' 16 | 17 | s.rubyforge_project = 'csso-rails' 18 | 19 | s.files = `git ls-files -z`.split("\x0").reject do |f| 20 | f.match(Regexp.union( 21 | %r{^gemfiles/}, 22 | %r{lib/csso/csso.js.erb}, 23 | %r{^spec/}, 24 | /^\./, 25 | /^Appraisals/, 26 | /^Gemfile/, 27 | /^Rakefile/ 28 | )) 29 | end 30 | s.files += [Csso::CSSO_JS_LIB] 31 | 32 | s.bindir = 'bin' 33 | s.executables = `git ls-files -z -- bin/*`.split("\x0").map do |f| 34 | File.basename(f) 35 | end 36 | s.require_paths = ['lib'] 37 | 38 | s.required_ruby_version = '>= 2.6.0' # rubocop:disable Gemspec/RequiredRubyVersion 39 | s.add_dependency 'execjs', '>= 1' 40 | 41 | s.add_development_dependency 'appraisal' 42 | s.add_development_dependency 'bundler' 43 | s.add_development_dependency 'minitest', '>= 5.0' 44 | s.add_development_dependency 'rake' 45 | end 46 | -------------------------------------------------------------------------------- /gemfiles/rails_5.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~>5.2" 6 | 7 | gemspec path: "../" 8 | -------------------------------------------------------------------------------- /gemfiles/rails_6.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~>6.0.1" 6 | 7 | gemspec path: "../" 8 | -------------------------------------------------------------------------------- /gemfiles/sprockets_2.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sprockets", "~>2.0" 6 | 7 | gemspec path: "../" 8 | -------------------------------------------------------------------------------- /gemfiles/sprockets_3.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sprockets", "~>3.0" 6 | 7 | gemspec path: "../" 8 | -------------------------------------------------------------------------------- /gemfiles/sprockets_4.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "sprockets", "~>4.0" 6 | gem "sass-rails", ">=6.0" 7 | 8 | gemspec path: "../" 9 | -------------------------------------------------------------------------------- /lib/csso-rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'csso' 4 | require 'csso/railtie' if defined?(Rails) 5 | -------------------------------------------------------------------------------- /lib/csso.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'csso/version' 4 | 5 | # base interface 6 | module Csso 7 | autoload :JsLib, 'csso/js_lib' 8 | autoload :Compressor, 'csso/compressor' 9 | 10 | def self.js_api 11 | @js_api ||= Csso::JsLib.new 12 | end 13 | 14 | def self.install(sprockets) 15 | unless sprockets 16 | raise 'no compatible sprockets found' unless Sprockets.respond_to? :register_compressor 17 | 18 | Sprockets.register_compressor('text/css', :csso, Compressor) 19 | return 20 | end 21 | if sprockets.respond_to? :register_compressor 22 | sprockets.register_compressor('text/css', :csso, Compressor) 23 | sprockets.css_compressor = :csso 24 | else 25 | # Sprockets::Compressors.register_css_compressor(:csso, 'Csso::Compressor::Legacy', :default => true) 26 | sprockets.css_compressor = Csso::Compressor::Legacy 27 | end 28 | end 29 | 30 | def self.optimize(css, maniac_mode = false, structural_optimization = true) 31 | if maniac_mode 32 | maniac_mode = 4 unless maniac_mode.is_a?(Integer) && maniac_mode > 0 33 | loop do 34 | prev_css = css 35 | css = Csso.js_api.compress(css, structural_optimization) 36 | maniac_mode -= 1 37 | break if maniac_mode <= 0 || prev_css == css 38 | end 39 | css 40 | else 41 | Csso.js_api.compress(css, structural_optimization) 42 | end 43 | end 44 | 45 | def self.optimize_with_sourcemap(css, filename, structural_optimization = true) 46 | return nil unless css.is_a?(String) 47 | return css if css.size <= 3 48 | 49 | Csso.js_api.compress_with_sourcemap(css, filename, structural_optimization) 50 | end 51 | 52 | # deprecated 53 | class Optimizer 54 | def optimize(css, structural_optimization = true) 55 | Csso.js_api.compress(css, structural_optimization) 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/csso/cli.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # encofing: utf-8 4 | 5 | require 'optparse' 6 | 7 | module Csso 8 | # :nodoc 9 | module CLI 10 | def self.run!(argv = ARGV) 11 | maniac = false 12 | opts = OptionParser.new do |opts| # rubocop:disable Lint/ShadowingOuterLocalVariable 13 | opts.version = Csso::VERSION 14 | opts.banner = "CSS Optimizer (ruby bindings by vasfed) version #{opts.version}" 15 | opts.separator '' 16 | opts.separator 'Usage:' 17 | opts.separator " #{opts.program_name} [options] FILE [FILE2 [FILE3 [...]]" 18 | opts.separator " #{opts.program_name} [options] < some_file.css" 19 | opts.separator '' 20 | opts.separator 'All input files are concatenated and fed to stdout after processing.' 21 | opts.separator '' 22 | 23 | opts.separator 'Options:' 24 | opts.on('-m', '--[no-]maniac', '"Maniac mode" optimizes input multiple times until optimization stops to give any results.') do |v| 25 | maniac = v 26 | end 27 | 28 | opts.on_tail('-v', '--version', 'Print version information') do 29 | return puts opts.ver 30 | end 31 | opts.on_tail('-h', '--help', 'Show this message') do 32 | return puts opts.help 33 | end 34 | end 35 | 36 | opts.parse!(argv) 37 | 38 | return puts opts.help if $stdin.tty? && argv.empty? 39 | 40 | ARGV.replace(argv) 41 | css = ARGF.read 42 | puts Csso.optimize(css, maniac) 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/csso/compressor.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Csso 4 | # sprockets-compatible compressor 5 | class Compressor 6 | def self.call(input) 7 | require 'csso' 8 | # TODO: settings? 9 | if input[:metadata] && input[:metadata][:map] 10 | css, map_json = Csso.optimize_with_sourcemap( 11 | input[:data], 12 | # Sprockets::PathUtils.split_subpath(input[:load_path], input[:filename]) 13 | # sprockets seems to ignore filenames here, so we may save some mem: 14 | 'uri' 15 | ) 16 | 17 | { 18 | data: css, 19 | map: Sprockets::SourceMapUtils.combine_source_maps(input[:metadata][:map], JSON.parse(map_json)) 20 | } 21 | else 22 | { data: Csso.optimize(input[:data], true) } 23 | end 24 | end 25 | 26 | # sprockets 2: 27 | 28 | def initialize(_path, &block) 29 | @block = block 30 | end 31 | 32 | def render(_context, _opts = {}) 33 | self.class.call(data: @block.call)[:data] 34 | end 35 | 36 | # for old sprockets 37 | class Legacy 38 | def self.compress(data) 39 | Compressor.call(data: data)[:data] 40 | end 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/csso/csso.js.erb: -------------------------------------------------------------------------------- 1 | <% 2 | # template for single-file csso lib 3 | 4 | def file(filename) 5 | File.read(filename).strip 6 | end 7 | 8 | def version package 9 | require 'json' 10 | JSON.parse(File.read(package))['version'] 11 | end 12 | 13 | %>/* 14 | <%= " THIS FILE IS AUTOGENERATED! DO NOT EDIT!\n See #{__FILE__} instead." %> 15 | 16 | Based on <%= version 'csso/package.json' %> revision <%= file 'csso/.git/refs/heads/master' %> 17 | */ 18 | 19 | console = { 20 | log: function(){}, 21 | error: function(txt){ 22 | throw txt; 23 | } 24 | }; 25 | 26 | <%= file 'csso/dist/csso.js' %> 27 | 28 | do_compression = function(css, structural){ 29 | return csso.minify(css, { 30 | restructure: structural 31 | }).css; 32 | }; 33 | 34 | do_compression_with_map = function(css, filename, structural){ 35 | var result = csso.minify(css, { 36 | restructure: structural, 37 | filename: filename, 38 | sourceMap: true 39 | }); 40 | return [result.css, result.map.toString()]; 41 | }; 42 | -------------------------------------------------------------------------------- /lib/csso/js_lib.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'execjs' 4 | 5 | module Csso 6 | # low-level wrapper around the js lib 7 | class JsLib 8 | def initialize(verbose = false) 9 | if verbose && ExecJS.runtime.is_a?(ExecJS::ExternalRuntime) 10 | warn "You're using ExecJS::ExternalRuntime, did you forget to add therubyracer or other execjs runtime to gemfile?" 11 | end 12 | 13 | lib = File.read(File.expand_path("../../#{CSSO_JS_LIB}", File.dirname(__FILE__))) 14 | raise 'cannot compile or what?' unless (@csso = ExecJS.runtime.compile(lib)) 15 | end 16 | 17 | def compress(css, structural_optimization = true) 18 | # TODO: raise ArgumentError, "expect css to be a String" unless css.is_a?(String) 19 | return nil unless css.is_a?(String) 20 | 21 | @csso.call('do_compression', css, structural_optimization) 22 | end 23 | 24 | def compress_with_sourcemap(css, filename, structural_optimization = true) 25 | return nil unless css.is_a?(String) 26 | 27 | @csso.call('do_compression_with_map', css, filename, structural_optimization) 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/csso/railtie.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'action_controller/railtie' 4 | 5 | module Csso 6 | # hook into rails init 7 | class Railtie < ::Rails::Railtie 8 | initializer 'csso.environment', after: 'sprockets.environment' do |app| 9 | # NB: app.assets may be nil, sprockets-rails creates env in after_initialize 10 | Csso.install(app.assets) 11 | end 12 | 13 | # saas-rails-3.2.4(and may be others) sets itself as default, ignoring config? => override :( 14 | initializer 'csso.setup', after: :setup_compression, group: :all do |app| 15 | app.config.assets.css_compressor = :csso if app.config.assets.enabled 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/csso/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Csso 4 | VERSION = '1.0.0' 5 | CSSO_JS_LIB = 'vendor/csso/csso.js' 6 | end 7 | -------------------------------------------------------------------------------- /spec/csso/csso_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'minitest/autorun' 4 | require 'csso' 5 | 6 | # Encoding.default_external = Encoding::UTF_8 7 | 8 | describe Csso do 9 | subject { Csso } 10 | 11 | it 'dummy test' do 12 | expect(1).must_equal 1 13 | end 14 | 15 | it 'should optimize css' do 16 | expect(subject.optimize("a {\ncolor: white; }")).must_equal 'a{color:#fff}' 17 | end 18 | 19 | it 'should optimize structure' do 20 | expect(subject.optimize("a {\ncolor: white; } a{color: red;}")).must_equal 'a{color:red}' 21 | end 22 | 23 | it 'should optimize structure' do 24 | expect(subject.optimize("a {\ncolor: white; } a{color: #ff0000;}")).must_equal 'a{color:red}' 25 | end 26 | 27 | it 'should optimize structure in maniac mode' do 28 | expect(subject.optimize("a {\ncolor: white; } a{color: #ff0000;}", true)).must_equal 'a{color:red}' 29 | end 30 | 31 | it 'should produce no error on empty input' do 32 | expect(subject.optimize(nil)).must_be_nil 33 | expect(subject.optimize('')).must_equal '' 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/csso/sprockets_integration_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'minitest/autorun' 4 | require 'fileutils' 5 | require 'csso' 6 | 7 | # Encoding.default_external = Encoding::UTF_8 8 | 9 | describe Csso do 10 | subject { Csso } 11 | let(:sprockets_env_without_csso) do 12 | begin 13 | require 'sprockets' 14 | rescue LoadError 15 | skip "Skipping sprockets integration, as there's no sprockets in this env" 16 | end 17 | Sprockets::Environment.new(File.expand_path('../', File.dirname(__FILE__))).tap do |e| 18 | e.append_path 'fixtures' 19 | e.config = e.config.merge(gzip_enabled: false).freeze if e.respond_to?(:config) 20 | # e.logger = Logger.new STDOUT 21 | end 22 | end 23 | let(:fixtures_dir) do 24 | File.expand_path('../fixtures', File.dirname(__FILE__)) 25 | end 26 | let(:result_dir) do 27 | d = File.expand_path('res', fixtures_dir) 28 | FileUtils.mkdir_p(d) 29 | d 30 | end 31 | let(:manifest_file) do 32 | File.expand_path('manifest.json', result_dir) 33 | end 34 | let(:manifest) do 35 | sprockets_env 36 | # unless Sprockets::VERSION <= '2.99' 37 | # Sprockets::Manifest.new(sprockets_env, result_dir, manifest_file) 38 | # else 39 | Sprockets::Manifest.new(sprockets_env, manifest_file) 40 | # end 41 | end 42 | let(:sprockets_env) do 43 | subject.install(sprockets_env_without_csso) 44 | sprockets_env_without_csso 45 | end 46 | 47 | it 'installs' do 48 | # sprockets_env.css_compressor.must_equal Csso::Compressor 49 | 50 | expect(manifest.environment).must_equal(sprockets_env) 51 | manifest.clobber 52 | res = manifest.compile('test.css') 53 | expect(res.size).must_equal 1 54 | expect([File.expand_path('../fixtures/test.css', __dir__), 'test.css']).must_include res.first 55 | expect(File.read(manifest_file)).wont_equal '{}' 56 | expect(sprockets_env['test.css'].source).must_equal '.class{color:red}' 57 | manifest.clobber 58 | end 59 | 60 | it 'compiles with sourcemap' do 61 | manifest.clobber 62 | begin 63 | require 'sass' 64 | rescue LoadError 65 | skip 'No sass in this env, skipping' 66 | end 67 | manifest.compile('test2.css') 68 | manifest.compile('test2.css.map') 69 | json = JSON.parse File.read(manifest_file) 70 | expect(json['assets']['test2.css']).must_match(/\.css$/) 71 | expect(sprockets_env['test2.css'].source).must_equal '.class,.class .other_class{color:red}.something{color:#000}.test2{color:#00f}' 72 | map = JSON.parse(sprockets_env['test2.css.map'].source) 73 | expect(map['sources'].size).must_equal 4 74 | manifest.clobber 75 | end 76 | 77 | it 'loads into rails' do 78 | begin 79 | require 'rails' 80 | rescue LoadError 81 | skip 'no rails in this env' 82 | end 83 | require 'sprockets/railtie' 84 | require 'csso/railtie' 85 | 86 | skip "rails 5 is not compatible with ruby 3" if RUBY_VERSION >= '3.0' && Rails::VERSION::MAJOR <= 5 87 | 88 | fd = fixtures_dir 89 | app = Class.new(Rails::Application) do 90 | config.root = fd 91 | config.eager_load = false 92 | config.assets.enabled = true 93 | 94 | config.paths['public'] = fd 95 | config.assets.paths = [fd] 96 | config.assets.prefix = 'res' 97 | 98 | config.assets.precompile = ['test.css'] 99 | config.active_support.deprecation = :log 100 | # config.active_support.deprecation = :raise 101 | end 102 | app.initialize! 103 | 104 | expect(app.config.assets.css_compressor).must_equal :csso 105 | expect(app.assets.css_compressor).must_equal(Csso::Compressor) if Sprockets::VERSION >= '3' 106 | 107 | require 'rake' 108 | res_dir = "#{fd}/res" 109 | if File.exist?(res_dir) 110 | puts 'Unclean from previous run' 111 | FileUtils.rm_rf(res_dir) 112 | end 113 | if File.exist?('tmp/cache') 114 | # we need clean cache, so rails will precompile for real 115 | puts 'Unclean cache from previous run' 116 | FileUtils.rm_rf('tmp/cache') 117 | end 118 | Rails.application.load_tasks 119 | ENV['RAILS_GROUPS'] ||= 'assets' 120 | ENV['RAILS_ENV'] ||= 'test' 121 | 122 | Csso::Compressor.stub(:call, { data: 'foo_this_is_mock' }) do 123 | Rake::Task['assets:precompile'].invoke 124 | end 125 | 126 | expect(Rails.application.assets['test.css'].source).must_equal 'foo_this_is_mock' 127 | 128 | FileUtils.rm_r(res_dir) 129 | FileUtils.rm_r("#{fd}/log") 130 | FileUtils.rm_rf('tmp/cache') if File.exist?('tmp/cache') 131 | end 132 | end 133 | -------------------------------------------------------------------------------- /spec/fixtures/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | // manifest.js for sprockets4 2 | //= link test.css -------------------------------------------------------------------------------- /spec/fixtures/test.css: -------------------------------------------------------------------------------- 1 | /* LaLaLa */ 2 | 3 | .class { 4 | color: #ff0000; 5 | } 6 | -------------------------------------------------------------------------------- /spec/fixtures/test2.css: -------------------------------------------------------------------------------- 1 | /* LaLaLa */ 2 | //= require ./test.css 3 | //= require ./test4.css 4 | 5 | .test2{ 6 | color: #0000ff; 7 | } 8 | -------------------------------------------------------------------------------- /spec/fixtures/test3.scss: -------------------------------------------------------------------------------- 1 | .something{ 2 | color: #000000; 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/test4.scss: -------------------------------------------------------------------------------- 1 | @import 'test3'; 2 | 3 | $color: #ff0000; 4 | 5 | .class { 6 | .other_class{ 7 | // comment blablabla 8 | color: $color; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /vendor/csso/csso.js: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS AUTOGENERATED! DO NOT EDIT! 3 | See lib/csso/csso.js.erb instead. 4 | 5 | Based on 5.0.5 revision 1ebc6709119284e3e1cd6d0b8d6c94074bb40921 6 | */ 7 | 8 | console = { 9 | log: function(){}, 10 | error: function(txt){ 11 | throw txt; 12 | } 13 | }; 14 | 15 | var csso=(()=>{var Bl=Object.create;var Bt=Object.defineProperty;var _l=Object.getOwnPropertyDescriptor;var Ul=Object.getOwnPropertyNames;var jl=Object.getPrototypeOf,ql=Object.prototype.hasOwnProperty;var Ue=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),b=(e,t)=>{for(var r in t)Bt(e,r,{get:t[r],enumerable:!0})},Ui=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ul(t))!ql.call(e,o)&&o!==r&&Bt(e,o,{get:()=>t[o],enumerable:!(n=_l(t,o))||n.enumerable});return e};var Hl=(e,t,r)=>(r=e!=null?Bl(jl(e)):{},Ui(t||!e||!e.__esModule?Bt(r,"default",{value:e,enumerable:!0}):r,e)),Wl=e=>Ui(Bt({},"__esModule",{value:!0}),e);var ta=Ue(Nr=>{var ea="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");Nr.encode=function(e){if(0<=e&&e{var ra=ta(),Mr=5,na=1<>1;return t?-r:r}Rr.encode=function(t){var r="",n,o=rc(t);do n=o&oa,o>>>=Mr,o>0&&(n|=ia),r+=ra.encode(n);while(o>0);return r};Rr.decode=function(t,r,n){var o=t.length,i=0,a=0,l,c;do{if(r>=o)throw new Error("Expected more digits in base 64 VLQ value.");if(c=ra.decode(t.charCodeAt(r++)),c===-1)throw new Error("Invalid base64 digit: "+t.charAt(r-1));l=!!(c&ia),c&=oa,i=i+(c<{function oc(e,t,r){if(t in e)return e[t];if(arguments.length===3)return r;throw new Error('"'+t+'" is a required argument.')}X.getArg=oc;var sa=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,ic=/^data:.+\,.+$/;function dt(e){var t=e.match(sa);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}X.urlParse=dt;function Ve(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}X.urlGenerate=Ve;var ac=32;function sc(e){var t=[];return function(r){for(var n=0;nac&&t.pop(),i}}var zr=sc(function(t){var r=t,n=dt(t);if(n){if(!n.path)return t;r=n.path}for(var o=X.isAbsolute(r),i=[],a=0,l=0;;)if(a=l,l=r.indexOf("/",a),l===-1){i.push(r.slice(a));break}else for(i.push(r.slice(a,l));l=0;l--)c=i[l],c==="."?i.splice(l,1):c===".."?s++:s>0&&(c===""?(i.splice(l+1,s),s=0):(i.splice(l,2),s--));return r=i.join("/"),r===""&&(r=o?"/":"."),n?(n.path=r,Ve(n)):r});X.normalize=zr;function la(e,t){e===""&&(e="."),t===""&&(t=".");var r=dt(t),n=dt(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),Ve(r);if(r||t.match(ic))return t;if(n&&!n.host&&!n.path)return n.host=t,Ve(n);var o=t.charAt(0)==="/"?t:zr(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=o,Ve(n)):o}X.join=la;X.isAbsolute=function(e){return e.charAt(0)==="/"||sa.test(e)};function lc(e,t){e===""&&(e="."),e=e.replace(/\/$/,"");for(var r=0;t.indexOf(e+"/")!==0;){var n=e.lastIndexOf("/");if(n<0||(e=e.slice(0,n),e.match(/^([^\/]+:\/)?\/*$/)))return t;++r}return Array(r+1).join("../")+t.substr(e.length+1)}X.relative=lc;var ca=function(){var e=Object.create(null);return!("__proto__"in e)}();function ua(e){return e}function cc(e){return pa(e)?"$"+e:e}X.toSetString=ca?ua:cc;function uc(e){return pa(e)?e.slice(1):e}X.fromSetString=ca?ua:uc;function pa(e){if(!e)return!1;var t=e.length;if(t<9||e.charCodeAt(t-1)!==95||e.charCodeAt(t-2)!==95||e.charCodeAt(t-3)!==111||e.charCodeAt(t-4)!==116||e.charCodeAt(t-5)!==111||e.charCodeAt(t-6)!==114||e.charCodeAt(t-7)!==112||e.charCodeAt(t-8)!==95||e.charCodeAt(t-9)!==95)return!1;for(var r=t-10;r>=0;r--)if(e.charCodeAt(r)!==36)return!1;return!0}function pc(e,t,r){var n=we(e.source,t.source);return n!==0||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:we(e.name,t.name)}X.compareByOriginalPositions=pc;function hc(e,t,r){var n;return n=e.originalLine-t.originalLine,n!==0||(n=e.originalColumn-t.originalColumn,n!==0||r)||(n=e.generatedColumn-t.generatedColumn,n!==0)||(n=e.generatedLine-t.generatedLine,n!==0)?n:we(e.name,t.name)}X.compareByOriginalPositionsNoSource=hc;function fc(e,t,r){var n=e.generatedLine-t.generatedLine;return n!==0||(n=e.generatedColumn-t.generatedColumn,n!==0||r)||(n=we(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:we(e.name,t.name)}X.compareByGeneratedPositionsDeflated=fc;function mc(e,t,r){var n=e.generatedColumn-t.generatedColumn;return n!==0||r||(n=we(e.source,t.source),n!==0)||(n=e.originalLine-t.originalLine,n!==0)||(n=e.originalColumn-t.originalColumn,n!==0)?n:we(e.name,t.name)}X.compareByGeneratedPositionsDeflatedNoLine=mc;function we(e,t){return e===t?0:e===null?1:t===null?-1:e>t?1:-1}function dc(e,t){var r=e.generatedLine-t.generatedLine;return r!==0||(r=e.generatedColumn-t.generatedColumn,r!==0)||(r=we(e.source,t.source),r!==0)||(r=e.originalLine-t.originalLine,r!==0)||(r=e.originalColumn-t.originalColumn,r!==0)?r:we(e.name,t.name)}X.compareByGeneratedPositionsInflated=dc;function gc(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}X.parseSourceMapInput=gc;function bc(e,t,r){if(t=t||"",e&&(e[e.length-1]!=="/"&&t[0]!=="/"&&(e+="/"),t=e+t),r){var n=dt(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var o=n.path.lastIndexOf("/");o>=0&&(n.path=n.path.substring(0,o+1))}t=la(Ve(n),t)}return zr(t)}X.computeSourceURL=bc});var fa=Ue(ha=>{var Fr=Kt(),Br=Object.prototype.hasOwnProperty,ze=typeof Map<"u";function ve(){this._array=[],this._set=ze?new Map:Object.create(null)}ve.fromArray=function(t,r){for(var n=new ve,o=0,i=t.length;o=0)return r}else{var n=Fr.toSetString(t);if(Br.call(this._set,n))return this._set[n]}throw new Error('"'+t+'" is not in the set.')};ve.prototype.at=function(t){if(t>=0&&t{var ma=Kt();function yc(e,t){var r=e.generatedLine,n=t.generatedLine,o=e.generatedColumn,i=t.generatedColumn;return n>r||n==r&&i>=o||ma.compareByGeneratedPositionsInflated(e,t)<=0}function Qt(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}Qt.prototype.unsortedForEach=function(t,r){this._array.forEach(t,r)};Qt.prototype.add=function(t){yc(this._last,t)?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))};Qt.prototype.toArray=function(){return this._sorted||(this._array.sort(ma.compareByGeneratedPositionsInflated),this._sorted=!0),this._array};da.MappingList=Qt});var ya=Ue(ba=>{var gt=aa(),Y=Kt(),$t=fa().ArraySet,xc=ga().MappingList;function se(e){e||(e={}),this._file=Y.getArg(e,"file",null),this._sourceRoot=Y.getArg(e,"sourceRoot",null),this._skipValidation=Y.getArg(e,"skipValidation",!1),this._sources=new $t,this._names=new $t,this._mappings=new xc,this._sourcesContents=null}se.prototype._version=3;se.fromSourceMap=function(t){var r=t.sourceRoot,n=new se({file:t.file,sourceRoot:r});return t.eachMapping(function(o){var i={generated:{line:o.generatedLine,column:o.generatedColumn}};o.source!=null&&(i.source=o.source,r!=null&&(i.source=Y.relative(r,i.source)),i.original={line:o.originalLine,column:o.originalColumn},o.name!=null&&(i.name=o.name)),n.addMapping(i)}),t.sources.forEach(function(o){var i=o;r!==null&&(i=Y.relative(r,o)),n._sources.has(i)||n._sources.add(i);var a=t.sourceContentFor(o);a!=null&&n.setSourceContent(o,a)}),n};se.prototype.addMapping=function(t){var r=Y.getArg(t,"generated"),n=Y.getArg(t,"original",null),o=Y.getArg(t,"source",null),i=Y.getArg(t,"name",null);this._skipValidation||this._validateMapping(r,n,o,i),o!=null&&(o=String(o),this._sources.has(o)||this._sources.add(o)),i!=null&&(i=String(i),this._names.has(i)||this._names.add(i)),this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:o,name:i})};se.prototype.setSourceContent=function(t,r){var n=t;this._sourceRoot!=null&&(n=Y.relative(this._sourceRoot,n)),r!=null?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[Y.toSetString(n)]=r):this._sourcesContents&&(delete this._sourcesContents[Y.toSetString(n)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))};se.prototype.applySourceMap=function(t,r,n){var o=r;if(r==null){if(t.file==null)throw new Error(`SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map's "file" property. Both were omitted.`);o=t.file}var i=this._sourceRoot;i!=null&&(o=Y.relative(i,o));var a=new $t,l=new $t;this._mappings.unsortedForEach(function(c){if(c.source===o&&c.originalLine!=null){var s=t.originalPositionFor({line:c.originalLine,column:c.originalColumn});s.source!=null&&(c.source=s.source,n!=null&&(c.source=Y.join(n,c.source)),i!=null&&(c.source=Y.relative(i,c.source)),c.originalLine=s.line,c.originalColumn=s.column,s.name!=null&&(c.name=s.name))}var u=c.source;u!=null&&!a.has(u)&&a.add(u);var p=c.name;p!=null&&!l.has(p)&&l.add(p)},this),this._sources=a,this._names=l,t.sources.forEach(function(c){var s=t.sourceContentFor(c);s!=null&&(n!=null&&(c=Y.join(n,c)),i!=null&&(c=Y.relative(i,c)),this.setSourceContent(c,s))},this)};se.prototype._validateMapping=function(t,r,n,o){if(r&&typeof r.line!="number"&&typeof r.column!="number")throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0&&!r&&!n&&!o)){if(t&&"line"in t&&"column"in t&&r&&"line"in r&&"column"in r&&t.line>0&&t.column>=0&&r.line>0&&r.column>=0&&n)return;throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:n,original:r,name:o}))}};se.prototype._serializeMappings=function(){for(var t=0,r=1,n=0,o=0,i=0,a=0,l="",c,s,u,p,h=this._mappings.toArray(),m=0,y=h.length;m0){if(!Y.compareByGeneratedPositionsInflated(s,h[m-1]))continue;c+=","}c+=gt.encode(s.generatedColumn-t),t=s.generatedColumn,s.source!=null&&(p=this._sources.indexOf(s.source),c+=gt.encode(p-a),a=p,c+=gt.encode(s.originalLine-1-o),o=s.originalLine-1,c+=gt.encode(s.originalColumn-n),n=s.originalColumn,s.name!=null&&(u=this._names.indexOf(s.name),c+=gt.encode(u-i),i=u)),l+=c}return l};se.prototype._generateSourcesContent=function(t,r){return t.map(function(n){if(!this._sourcesContents)return null;r!=null&&(n=Y.relative(r,n));var o=Y.toSetString(n);return Object.prototype.hasOwnProperty.call(this._sourcesContents,o)?this._sourcesContents[o]:null},this)};se.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(t.file=this._file),this._sourceRoot!=null&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t};se.prototype.toString=function(){return JSON.stringify(this.toJSON())};ba.SourceMapGenerator=se});var kd={};b(kd,{minify:()=>yd,minifyBlock:()=>xd,syntax:()=>Cr,utils:()=>Bi,version:()=>ji});var ji="5.0.5";var Cr={};b(Cr,{compress:()=>Fi,find:()=>cd,findAll:()=>pd,findLast:()=>ud,fromPlainObject:()=>hd,generate:()=>sd,lexer:()=>od,parse:()=>ad,specificity:()=>wr,toPlainObject:()=>fd,tokenize:()=>id,walk:()=>ld});var Ee={};b(Ee,{AtKeyword:()=>M,BadString:()=>Ne,BadUrl:()=>K,CDC:()=>W,CDO:()=>pe,Colon:()=>R,Comma:()=>Q,Comment:()=>I,Delim:()=>g,Dimension:()=>k,EOF:()=>st,Function:()=>x,Hash:()=>A,Ident:()=>f,LeftCurlyBracket:()=>_,LeftParenthesis:()=>P,LeftSquareBracket:()=>H,Number:()=>d,Percentage:()=>L,RightCurlyBracket:()=>G,RightParenthesis:()=>S,RightSquareBracket:()=>$,Semicolon:()=>q,String:()=>V,Url:()=>U,WhiteSpace:()=>v});var st=0,f=1,x=2,M=3,A=4,V=5,Ne=6,U=7,K=8,g=9,d=10,L=11,k=12,v=13,pe=14,W=15,R=16,q=17,Q=18,H=19,$=20,P=21,S=22,_=23,G=24,I=25;function j(e){return e>=48&&e<=57}function oe(e){return j(e)||e>=65&&e<=70||e>=97&&e<=102}function Ut(e){return e>=65&&e<=90}function Yl(e){return e>=97&&e<=122}function Vl(e){return Ut(e)||Yl(e)}function Gl(e){return e>=128}function _t(e){return Vl(e)||Gl(e)||e===95}function lt(e){return _t(e)||j(e)||e===45}function Kl(e){return e>=0&&e<=8||e===11||e>=14&&e<=31||e===127}function ct(e){return e===10||e===13||e===12}function he(e){return ct(e)||e===32||e===9}function re(e,t){return!(e!==92||ct(t)||t===0)}function je(e,t,r){return e===45?_t(t)||t===45||re(t,r):_t(e)?!0:e===92?re(e,t):!1}function jt(e,t,r){return e===43||e===45?j(t)?2:t===46&&j(r)?3:0:e===46?j(t)?2:0:j(e)?1:0}function qt(e){return e===65279||e===65534?1:0}var Ar=new Array(128),Ql=128,ut=130,Er=131,Ht=132,Tr=133;for(let e=0;ee.length)return!1;for(let o=t;o=0&&he(e.charCodeAt(t));t--);return t+1}function pt(e,t){for(;t=55296&&t<=57343||t>1114111)&&(t=65533),String.fromCodePoint(t)}var He=["EOF-token","ident-token","function-token","at-keyword-token","hash-token","string-token","bad-string-token","url-token","bad-url-token","delim-token","number-token","percentage-token","dimension-token","whitespace-token","CDO-token","CDC-token","colon-token","semicolon-token","comma-token","[-token","]-token","(-token",")-token","{-token","}-token"];function We(e=null,t){return e===null||e.length0?qt(t.charCodeAt(0)):0,o=We(e.lines,r),i=We(e.columns,r),a=e.startLine,l=e.startColumn;for(let c=n;c{}){t=String(t||"");let n=t.length,o=We(this.offsetAndType,t.length+1),i=We(this.balance,t.length+1),a=0,l=0,c=0,s=-1;for(this.offsetAndType=null,this.balance=null,r(t,(u,p,h)=>{switch(u){default:i[a]=n;break;case l:{let m=c&ae;for(c=i[m],l=c>>Te,i[a]=m,i[m++]=a;m>Te:0}lookupOffset(t){return t+=this.tokenIndex,t0?t>Te,this.tokenEnd=r&ae):(this.tokenIndex=this.tokenCount,this.next())}next(){let t=this.tokenIndex+1;t>Te,this.tokenEnd=t&ae):(this.eof=!0,this.tokenIndex=this.tokenCount,this.tokenType=0,this.tokenStart=this.tokenEnd=this.source.length)}skipSC(){for(;this.tokenType===13||this.tokenType===25;)this.next()}skipUntilBalanced(t,r){let n=t,o,i;e:for(;n0?this.offsetAndType[n-1]&ae:this.firstCharOffset,r(this.source.charCodeAt(i))){case 1:break e;case 2:n++;break e;default:this.balance[o]===n&&(n=o)}}this.skip(n-this.tokenIndex)}forEachToken(t){for(let r=0,n=this.firstCharOffset;r>Te;n=a,t(l,o,a,r)}}dump(){let t=new Array(this.tokenCount);return this.forEachToken((r,n,o,i)=>{t[i]={idx:i,type:He[r],chunk:this.source.substring(n,o),balance:this.balance[i]}}),t}};function Le(e,t){function r(p){return p=e.length){sString(u+m+1).padStart(c)+" |"+h).join(` 17 | `)}let i=e.split(/\r\n?|\n|\f/),a=Math.max(1,t-n)-1,l=Math.min(t+n,i.length+1),c=Math.max(4,String(l).length)+1,s=0;r+=(Gi.length-1)*(i[t-1].substr(0,r-1).match(/\t/g)||[]).length,r>Pr&&(s=r-Vi+3,r=Vi-2);for(let u=a;u<=l;u++)u>=0&&u0&&i[u].length>s?"\u2026":"")+i[u].substr(s,Pr-2)+(i[u].length>s+Pr-1?"\u2026":""));return[o(a,t),new Array(r+c+2).join("-")+"^",o(t,l)].filter(Boolean).join(` 18 | `)}function Ir(e,t,r,n,o){return Object.assign(Re("SyntaxError",e),{source:t,offset:r,line:n,column:o,sourceFragment(a){return Ki({source:t,line:n,column:o},isNaN(a)?0:a)},get formattedMessage(){return`Parse error: ${e} 19 | `+Ki({source:t,line:n,column:o},2)}})}function Qi(e){let t=this.createList(),r=!1,n={recognizer:e};for(;!this.eof;){switch(this.tokenType){case 25:this.next();continue;case 13:r=!0,this.next();continue}let o=e.getNode.call(this,n);if(o===void 0)break;r&&(e.onWhiteSpace&&e.onWhiteSpace.call(this,o,t,n),r=!1),t.push(o)}return r&&e.onWhiteSpace&&e.onWhiteSpace.call(this,null,t,n),t}var $i=()=>{},Zl=33,Jl=35,Or=59,Xi=123,Zi=0;function ec(e){return function(){return this[e]()}}function Dr(e){let t=Object.create(null);for(let r in e){let n=e[r],o=n.parse||n;o&&(t[r]=o)}return t}function tc(e){let t={context:Object.create(null),scope:Object.assign(Object.create(null),e.scope),atrule:Dr(e.atrule),pseudo:Dr(e.pseudo),node:Dr(e.node)};for(let r in e.parseContext)switch(typeof e.parseContext[r]){case"function":t.context[r]=e.parseContext[r];break;case"string":t.context[r]=ec(e.parseContext[r]);break}return{config:t,...t,...t.node}}function Ji(e){let t="",r="",n=!1,o=$i,i=!1,a=new Gt,l=Object.assign(new mt,tc(e||{}),{parseAtrulePrelude:!0,parseRulePrelude:!0,parseValue:!0,parseCustomProperty:!1,readSequence:Qi,consumeUntilBalanceEnd:()=>0,consumeUntilLeftCurlyBracket(s){return s===Xi?1:0},consumeUntilLeftCurlyBracketOrSemicolon(s){return s===Xi||s===Or?1:0},consumeUntilExclamationMarkOrSemicolon(s){return s===Zl||s===Or?1:0},consumeUntilSemicolonIncluded(s){return s===Or?2:0},createList(){return new w},createSingleNodeList(s){return new w().appendData(s)},getFirstListNode(s){return s&&s.first},getLastListNode(s){return s&&s.last},parseWithFallback(s,u){let p=this.tokenIndex;try{return s.call(this)}catch(h){if(i)throw h;let m=u.call(this,p);return i=!0,o(h,m),i=!1,m}},lookupNonWSType(s){let u;do if(u=this.lookupType(s++),u!==13)return u;while(u!==Zi);return Zi},charCodeAt(s){return s>=0&&sm.toUpperCase()),p=`${/[[\](){}]/.test(u)?`"${u}"`:u} is expected`,h=this.tokenStart;switch(s){case 1:this.tokenType===2||this.tokenType===7?(h=this.tokenEnd-1,p="Identifier is expected but function found"):p="Identifier is expected";break;case 4:this.isDelim(Jl)&&(this.next(),h++,p="Name is expected");break;case 11:this.tokenType===10&&(h=this.tokenEnd,p="Percent sign is expected");break}this.error(p,h)}this.next()},eatIdent(s){(this.tokenType!==1||this.lookupValue(0,s)===!1)&&this.error(`Identifier "${s}" is expected`),this.next()},eatDelim(s){this.isDelim(s)||this.error(`Delim "${String.fromCharCode(s)}" is expected`),this.next()},getLocation(s,u){return n?a.getLocationRange(s,u,r):null},getLocationFromList(s){if(n){let u=this.getFirstListNode(s),p=this.getLastListNode(s);return a.getLocationRange(u!==null?u.loc.start.offset-a.startOffset:this.tokenStart,p!==null?p.loc.end.offset-a.startOffset:this.tokenStart,r)}return null},error(s,u){let p=typeof u<"u"&&u",n=Boolean(u.positions),o=typeof u.onParseError=="function"?u.onParseError:$i,i=!1,l.parseAtrulePrelude="parseAtrulePrelude"in u?Boolean(u.parseAtrulePrelude):!0,l.parseRulePrelude="parseRulePrelude"in u?Boolean(u.parseRulePrelude):!0,l.parseValue="parseValue"in u?Boolean(u.parseValue):!0,l.parseCustomProperty="parseCustomProperty"in u?Boolean(u.parseCustomProperty):!1;let{context:p="default",onComment:h}=u;if(!(p in l.context))throw new Error("Unknown context `"+p+"`");typeof h=="function"&&l.forEachToken((y,T,N)=>{if(y===25){let C=l.getLocation(T,N),D=ke(t,N-2,N,"*/")?t.slice(T+2,N-2):t.slice(T+2,N);h(D,C)}});let m=l.context[p].call(l,u);return l.eof||l.error(),m},{SyntaxError:Ir,config:l.config})}var ka=Hl(ya(),1),xa=new Set(["Atrule","Selector","Declaration"]);function wa(e){let t=new ka.SourceMapGenerator,r={line:1,column:0},n={line:0,column:0},o={line:1,column:0},i={generated:o},a=1,l=0,c=!1,s=e.node;e.node=function(h){if(h.loc&&h.loc.start&&xa.has(h.type)){let m=h.loc.start.line,y=h.loc.start.column-1;(n.line!==m||n.column!==y)&&(n.line=m,n.column=y,r.line=a,r.column=l,c&&(c=!1,(r.line!==o.line||r.column!==o.column)&&t.addMapping(i)),c=!0,t.addMapping({source:h.loc.source,original:n,generated:r}))}s.call(this,h),c&&xa.has(h.type)&&(o.line=a,o.column=l)};let u=e.emit;e.emit=function(h,m,y){for(let T=0;TUr,spec:()=>Sc});var kc=43,wc=45,_r=(e,t)=>{if(e===9&&(e=t),typeof e=="string"){let r=e.charCodeAt(0);return r>127?32768:r<<8}return e},va=[[1,1],[1,2],[1,7],[1,8],[1,"-"],[1,10],[1,11],[1,12],[1,15],[1,21],[3,1],[3,2],[3,7],[3,8],[3,"-"],[3,10],[3,11],[3,12],[3,15],[4,1],[4,2],[4,7],[4,8],[4,"-"],[4,10],[4,11],[4,12],[4,15],[12,1],[12,2],[12,7],[12,8],[12,"-"],[12,10],[12,11],[12,12],[12,15],["#",1],["#",2],["#",7],["#",8],["#","-"],["#",10],["#",11],["#",12],["#",15],["-",1],["-",2],["-",7],["-",8],["-","-"],["-",10],["-",11],["-",12],["-",15],[10,1],[10,2],[10,7],[10,8],[10,10],[10,11],[10,12],[10,"%"],[10,15],["@",1],["@",2],["@",7],["@",8],["@","-"],["@",15],[".",10],[".",11],[".",12],["+",10],["+",11],["+",12],["/","*"]],vc=va.concat([[1,4],[12,4],[4,4],[3,21],[3,5],[3,16],[11,11],[11,12],[11,2],[11,"-"],[22,1],[22,2],[22,11],[22,12],[22,4],[22,"-"]]);function Sa(e){let t=new Set(e.map(([r,n])=>_r(r)<<16|_r(n)));return function(r,n,o){let i=_r(n,o),a=o.charCodeAt(0);return(a===wc&&n!==1&&n!==2&&n!==15||a===kc?t.has(r<<16|a<<8):t.has(r<<16|i))&&this.emit(" ",13,!0),i}}var Sc=Sa(va),Ur=Sa(vc);var Cc=92;function Ac(e,t){if(typeof t=="function"){let r=null;e.children.forEach(n=>{r!==null&&t.call(this,r),this.node(n),r=n});return}e.children.forEach(this.node,this)}function Ec(e){Le(e,(t,r,n)=>{this.token(t,e.slice(r,n))})}function Ca(e){let t=new Map;for(let r in e.node){let n=e.node[r];typeof(n.generate||n)=="function"&&t.set(r,n.generate||n)}return function(r,n){let o="",i=0,a={node(c){if(t.has(c.type))t.get(c.type).call(l,c);else throw new Error("Unknown node type: "+c.type)},tokenBefore:Ur,token(c,s){i=this.tokenBefore(i,c,s),this.emit(s,c,!1),c===9&&s.charCodeAt(0)===Cc&&this.emit(` 20 | `,13,!0)},emit(c){o+=c},result(){return o}};n&&(typeof n.decorator=="function"&&(a=n.decorator(a)),n.sourceMap&&(a=wa(a)),n.mode in Xt&&(a.tokenBefore=Xt[n.mode]));let l={node:c=>a.node(c),children:Ac,token:(c,s)=>a.token(c,s),tokenize:Ec};return a.node(r),a.result()}}function Aa(e){return{fromPlainObject(t){return e(t,{enter(r){r.children&&!(r.children instanceof w)&&(r.children=new w().fromArray(r.children))}}),t},toPlainObject(t){return e(t,{leave(r){r.children&&r.children instanceof w&&(r.children=r.children.toArray())}}),t}}}var{hasOwnProperty:jr}=Object.prototype,bt=function(){};function Ea(e){return typeof e=="function"?e:bt}function Ta(e,t){return function(r,n,o){r.type===t&&e.call(this,r,n,o)}}function Tc(e,t){let r=t.structure,n=[];for(let o in r){if(jr.call(r,o)===!1)continue;let i=r[o],a={name:o,type:!1,nullable:!1};Array.isArray(i)||(i=[i]);for(let l of i)l===null?a.nullable=!0:typeof l=="string"?a.type="node":Array.isArray(l)&&(a.type="list");a.type&&n.push(a)}return n.length?{context:t.walkContext,fields:n}:null}function Lc(e){let t={};for(let r in e.node)if(jr.call(e.node,r)){let n=e.node[r];if(!n.structure)throw new Error("Missed `structure` field in `"+r+"` node type definition");t[r]=Tc(r,n)}return t}function La(e,t){let r=e.fields.slice(),n=e.context,o=typeof n=="string";return t&&r.reverse(),function(i,a,l,c){let s;o&&(s=a[n],a[n]=i);for(let u of r){let p=i[u.name];if(!u.nullable||p){if(u.type==="list"){if(t?p.reduceRight(c,!1):p.reduce(c,!1))return!0}else if(l(p))return!0}}o&&(a[n]=s)}}function Pa({StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:o}){return{Atrule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Rule:{StyleSheet:e,Atrule:t,Rule:r,Block:n},Declaration:{StyleSheet:e,Atrule:t,Rule:r,Block:n,DeclarationList:o}}}function Ia(e){let t=Lc(e),r={},n={},o=Symbol("break-walk"),i=Symbol("skip-node");for(let s in t)jr.call(t,s)&&t[s]!==null&&(r[s]=La(t[s],!1),n[s]=La(t[s],!0));let a=Pa(r),l=Pa(n),c=function(s,u){function p(C,D,Ae){let B=h.call(N,C,D,Ae);return B===o?!0:B===i?!1:!!(y.hasOwnProperty(C.type)&&y[C.type](C,N,p,T)||m.call(N,C,D,Ae)===o)}let h=bt,m=bt,y=r,T=(C,D,Ae,B)=>C||p(D,Ae,B),N={break:o,skip:i,root:s,stylesheet:null,atrule:null,atrulePrelude:null,rule:null,selector:null,block:null,declaration:null,function:null};if(typeof u=="function")h=u;else if(u&&(h=Ea(u.enter),m=Ea(u.leave),u.reverse&&(y=n),u.visit)){if(a.hasOwnProperty(u.visit))y=u.reverse?l[u.visit]:a[u.visit];else if(!t.hasOwnProperty(u.visit))throw new Error("Bad value `"+u.visit+"` for `visit` option (should be: "+Object.keys(t).sort().join(", ")+")");h=Ta(h,u.visit),m=Ta(m,u.visit)}if(h===bt&&m===bt)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");p(s)};return c.break=o,c.skip=i,c.find=function(s,u){let p=null;return c(s,function(h,m,y){if(u.call(this,h,m,y))return p=h,o}),p},c.findLast=function(s,u){let p=null;return c(s,{reverse:!0,enter(h,m,y){if(u.call(this,h,m,y))return p=h,o}}),p},c.findAll=function(s,u){let p=[];return c(s,function(h,m,y){u.call(this,h,m,y)&&p.push(h)}),p},c}function Pc(e){return e}function Ic(e){let{min:t,max:r,comma:n}=e;return t===0&&r===0?n?"#?":"*":t===0&&r===1?"?":t===1&&r===0?n?"#":"+":t===1&&r===1?"":(n?"#":"")+(t===r?"{"+t+"}":"{"+t+","+(r!==0?r:"")+"}")}function Oc(e){switch(e.type){case"Range":return" ["+(e.min===null?"-\u221E":e.min)+","+(e.max===null?"\u221E":e.max)+"]";default:throw new Error("Unknown node type `"+e.type+"`")}}function Dc(e,t,r,n){let o=e.combinator===" "||n?e.combinator:" "+e.combinator+" ",i=e.terms.map(a=>qr(a,t,r,n)).join(o);return e.explicit||r?(n||i[0]===","?"[":"[ ")+i+(n?"]":" ]"):i}function qr(e,t,r,n){let o;switch(e.type){case"Group":o=Dc(e,t,r,n)+(e.disallowEmpty?"!":"");break;case"Multiplier":return qr(e.term,t,r,n)+t(Ic(e),e);case"Type":o="<"+e.name+(e.opts?t(Oc(e.opts),e.opts):"")+">";break;case"Property":o="<'"+e.name+"'>";break;case"Keyword":o=e.name;break;case"AtKeyword":o="@"+e.name;break;case"Function":o=e.name+"(";break;case"String":case"Token":o=e.value;break;case"Comma":o=",";break;default:throw new Error("Unknown node type `"+e.type+"`")}return t(o,e)}function Ge(e,t){let r=Pc,n=!1,o=!1;return typeof t=="function"?r=t:t&&(n=Boolean(t.forceBraces),o=Boolean(t.compact),typeof t.decorate=="function"&&(r=t.decorate)),qr(e,r,n,o)}var Oa={offset:0,line:1,column:1};function Nc(e,t){let r=e.tokens,n=e.longestMatch,o=n1?(u=Zt(i||t,"end")||yt(Oa,s),p=yt(u)):(u=Zt(i,"start")||yt(Zt(t,"start")||Oa,s.slice(0,a)),p=Zt(i,"end")||yt(u,s.substr(a,l))),{css:s,mismatchOffset:a,mismatchLength:l,start:u,end:p}}function Zt(e,t){let r=e&&e.loc&&e.loc[t];return r?"line"in r?yt(r):r:null}function yt({offset:e,line:t,column:r},n){let o={offset:e,line:t,column:r};if(n){let i=n.split(/\n|\r\n?|\f/);o.offset+=n.length,o.line+=i.length-1,o.column=i.length===1?o.column+n.length:i.pop().length+1}return o}var Ke=function(e,t){let r=Re("SyntaxReferenceError",e+(t?" `"+t+"`":""));return r.reference=t,r},Da=function(e,t,r,n){let o=Re("SyntaxMatchError",e),{css:i,mismatchOffset:a,mismatchLength:l,start:c,end:s}=Nc(n,r);return o.rawMessage=e,o.syntax=t?Ge(t):"",o.css=i,o.mismatchOffset=a,o.mismatchLength=l,o.message=e+` 21 | syntax: `+o.syntax+` 22 | value: `+(i||"")+` 23 | --------`+new Array(o.mismatchOffset+1).join("-")+"^",Object.assign(o,c),o.loc={source:r&&r.loc&&r.loc.source||"",start:c,end:s},o};var Jt=new Map,Qe=new Map,er=45,Z=Mc,me=Rc;function tr(e,t){return t=t||0,e.length-t>=2&&e.charCodeAt(t)===er&&e.charCodeAt(t+1)===er}function Na(e,t){if(t=t||0,e.length-t>=3&&e.charCodeAt(t)===er&&e.charCodeAt(t+1)!==er){let r=e.indexOf("-",t+2);if(r!==-1)return e.substring(t,r+1)}return""}function Mc(e){if(Jt.has(e))return Jt.get(e);let t=e.toLowerCase(),r=Jt.get(t);if(r===void 0){let n=tr(t,0),o=n?"":Na(t,0);r=Object.freeze({basename:t.substr(o.length),name:t,prefix:o,vendor:o,custom:n})}return Jt.set(e,r),r}function Rc(e){if(Qe.has(e))return Qe.get(e);let t=e,r=e[0];r==="/"?r=e[1]==="/"?"//":"/":r!=="_"&&r!=="*"&&r!=="$"&&r!=="#"&&r!=="+"&&r!=="&"&&(r="");let n=tr(t,r.length);if(!n&&(t=t.toLowerCase(),Qe.has(t))){let l=Qe.get(t);return Qe.set(e,l),l}let o=n?"":Na(t,r.length),i=t.substr(0,r.length+o.length),a=Object.freeze({basename:t.substr(i.length),name:t.substr(r.length),hack:r,vendor:o,prefix:i,custom:n});return Qe.set(e,a),a}var rr=["initial","inherit","unset","revert","revert-layer"];var kt=43,de=45,Hr=110,$e=!0,Fc=!1;function Yr(e,t){return e!==null&&e.type===9&&e.value.charCodeAt(0)===t}function xt(e,t,r){for(;e!==null&&(e.type===13||e.type===25);)e=r(++t);return t}function Pe(e,t,r,n){if(!e)return 0;let o=e.value.charCodeAt(t);if(o===kt||o===de){if(r)return 0;t++}for(;t6)return 0}return n}function nr(e,t,r){if(!e)return 0;for(;Gr(r(t),Ra);){if(++e>6)return 0;t++}return t}function Kr(e,t){let r=0;if(e===null||e.type!==1||!xe(e.value,0,_c)||(e=t(++r),e===null))return 0;if(Gr(e,Bc))return e=t(++r),e===null?0:e.type===1?nr(wt(e,0,!0),++r,t):Gr(e,Ra)?nr(1,++r,t):0;if(e.type===10){let n=wt(e,1,!0);return n===0?0:(e=t(++r),e===null?r:e.type===12||e.type===10?!Uc(e,Ma)||!wt(e,1,!1)?0:r+1:nr(n,r,t))}return e.type===12?nr(wt(e,1,!0),++r,t):0}var jc=["calc(","-moz-calc(","-webkit-calc("],Qr=new Map([[2,22],[21,22],[19,20],[23,24]]),qc=["cm","mm","q","in","pt","pc","px","em","rem","ex","rex","cap","rcap","ch","rch","ic","ric","lh","rlh","vw","svw","lvw","dvw","vh","svh","lvh","dvh","vi","svi","lvi","dvi","vb","svb","lvb","dvb","vmin","svmin","lvmin","dvmin","vmax","svmax","lvmax","dvmax","cqw","cqh","cqi","cqb","cqmin","cqmax"],Hc=["deg","grad","rad","turn"],Wc=["s","ms"],Yc=["hz","khz"],Vc=["dpi","dpcm","dppx","x"],Gc=["fr"],Kc=["db"],Qc=["st"];function ue(e,t){return te.max&&typeof e.max!="string")return!0}return!1}function $c(e,t){let r=0,n=[],o=0;e:do{switch(e.type){case 24:case 22:case 20:if(e.type!==r)break e;if(r=n.pop(),n.length===0){o++;break e}break;case 2:case 21:case 19:case 23:n.push(r),r=Qr.get(e.type);break}o++}while(e=t(o));return o}function le(e){return function(t,r,n){return t===null?0:t.type===2&&Ba(t.value,jc)?$c(t,r):e(t,r,n)}}function z(e){return function(t){return t===null||t.type!==e?0:1}}function Xc(e){if(e===null||e.type!==1)return 0;let t=e.value.toLowerCase();return Ba(t,rr)||Fa(t,"default")?0:1}function Zc(e){return e===null||e.type!==1||ue(e.value,0)!==45||ue(e.value,1)!==45?0:1}function Jc(e){if(e===null||e.type!==4)return 0;let t=e.value.length;if(t!==4&&t!==5&&t!==7&&t!==9)return 0;for(let r=1;r/[a-zA-Z0-9\-]/.test(String.fromCharCode(t))?1:0),Ya={" ":1,"&&":2,"||":3,"|":4};function lr(e){return e.substringToPos(e.findWsEnd(e.pos))}function Xe(e){let t=e.pos;for(;t=128||vt[r]===0)break}return e.pos===t&&e.error("Expect a keyword"),e.substringToPos(t)}function cr(e){let t=e.pos;for(;t57)break}return e.pos===t&&e.error("Expect a number"),e.substringToPos(t)}function yu(e){let t=e.str.indexOf("'",e.pos+1);return t===-1&&(e.pos=e.str.length,e.error("Expect an apostrophe")),e.substringToPos(t+1)}function Va(e){let t=null,r=null;return e.eat(sr),t=cr(e),e.charCode()===rn?(e.pos++,e.charCode()!==Ha&&(r=cr(e))):r=t,e.eat(Ha),{min:Number(t),max:r?Number(r):0}}function xu(e){let t=null,r=!1;switch(e.charCode()){case Qa:e.pos++,t={min:0,max:0};break;case tn:e.pos++,t={min:1,max:0};break;case Jr:e.pos++,t={min:0,max:1};break;case en:e.pos++,r=!0,e.charCode()===sr?t=Va(e):e.charCode()===Jr?(e.pos++,t={min:0,max:0}):t={min:1,max:0};break;case sr:t=Va(e);break;default:return null}return{type:"Multiplier",comma:r,min:t.min,max:t.max,term:null}}function Ze(e,t){let r=xu(e);return r!==null?(r.term=t,e.charCode()===en&&e.charCodeAt(e.pos-1)===tn?Ze(e,r):r):t}function Zr(e){let t=e.peek();return t===""?null:{type:"Token",value:t}}function ku(e){let t;return e.eat(nn),e.eat(ar),t=Xe(e),e.eat(ar),e.eat($a),Ze(e,{type:"Property",name:t})}function wu(e){let t=null,r=null,n=1;return e.eat(ur),e.charCode()===ja&&(e.peek(),n=-1),n==-1&&e.charCode()===Wa?e.peek():(t=n*Number(cr(e)),vt[e.charCode()]!==0&&(t+=Xe(e))),lr(e),e.eat(rn),lr(e),e.charCode()===Wa?e.peek():(n=1,e.charCode()===ja&&(e.peek(),n=-1),r=n*Number(cr(e)),vt[e.charCode()]!==0&&(r+=Xe(e))),e.eat(on),{type:"Range",min:t,max:r}}function vu(e){let t,r=null;return e.eat(nn),t=Xe(e),e.charCode()===Ka&&e.nextCharCode()===gu&&(e.pos+=2,t+="()"),e.charCodeAt(e.findWsEnd(e.pos))===ur&&(lr(e),r=wu(e)),e.eat($a),Ze(e,{type:"Type",name:t,opts:r})}function Su(e){let t=Xe(e);return e.charCode()===Ka?(e.pos++,{type:"Function",name:t}):Ze(e,{type:"Keyword",name:t})}function Cu(e,t){function r(o,i){return{type:"Group",terms:o,combinator:i,disallowEmpty:!1,explicit:!1}}let n;for(t=Object.keys(t).sort((o,i)=>Ya[o]-Ya[i]);t.length>0;){n=t.shift();let o=0,i=0;for(;o1&&(e.splice(i,o-i,r(e.slice(i,o),n)),o=i+1),i=-1))}i!==-1&&t.length&&e.splice(i,o-i,r(e.slice(i,o),n))}return n}function Xa(e){let t=[],r={},n,o=null,i=e.pos;for(;n=Eu(e);)n.type!=="Spaces"&&(n.type==="Combinator"?((o===null||o.type==="Combinator")&&(e.pos=i,e.error("Unexpected combinator")),r[n.value]=!0):o!==null&&o.type!=="Combinator"&&(r[" "]=!0,t.push({type:"Combinator",value:" "})),t.push(n),o=n,i=e.pos);return o!==null&&o.type==="Combinator"&&(e.pos-=i,e.error("Unexpected combinator")),{type:"Group",terms:t,combinator:Cu(t,r)||" ",disallowEmpty:!1,explicit:!1}}function Au(e){let t;return e.eat(ur),t=Xa(e),e.eat(on),t.explicit=!0,e.charCode()===Ga&&(e.pos++,t.disallowEmpty=!0),t}function Eu(e){let t=e.charCode();if(t<128&&vt[t]===1)return Su(e);switch(t){case on:break;case ur:return Ze(e,Au(e));case nn:return e.nextCharCode()===ar?ku(e):vu(e);case qa:return{type:"Combinator",value:e.substringToPos(e.pos+(e.nextCharCode()===qa?2:1))};case Ua:return e.pos++,e.eat(Ua),{type:"Combinator",value:"&&"};case rn:return e.pos++,{type:"Comma"};case ar:return Ze(e,{type:"String",value:yu(e)});case du:case pu:case hu:case mu:case fu:return{type:"Spaces",value:lr(e)};case bu:return t=e.nextCharCode(),t<128&&vt[t]===1?(e.pos++,{type:"AtKeyword",name:Xe(e)}):Zr(e);case Qa:case tn:case Jr:case en:case Ga:break;case sr:if(t=e.nextCharCode(),t<48||t>57)return Zr(e);break;default:return Zr(e)}}function St(e){let t=new ir(e),r=Xa(t);return t.pos!==e.length&&t.error("Unexpected input"),r.terms.length===1&&r.terms[0].type==="Group"?r.terms[0]:r}var Ct=function(){};function Za(e){return typeof e=="function"?e:Ct}function an(e,t,r){function n(a){switch(o.call(r,a),a.type){case"Group":a.terms.forEach(n);break;case"Multiplier":n(a.term);break;case"Type":case"Property":case"Keyword":case"AtKeyword":case"Function":case"String":case"Token":case"Comma":break;default:throw new Error("Unknown type: "+a.type)}i.call(r,a)}let o=Ct,i=Ct;if(typeof t=="function"?o=t:t&&(o=Za(t.enter),i=Za(t.leave)),o===Ct&&i===Ct)throw new Error("Neither `enter` nor `leave` walker handler is set or both aren't a function");n(e,r)}var Lu={decorator(e){let t=[],r=null;return{...e,node(n){let o=r;r=n,e.node.call(this,n),r=o},emit(n,o,i){t.push({type:o,value:n,node:i?null:r})},result(){return t}}}};function Pu(e){let t=[];return Le(e,(r,n,o)=>t.push({type:r,value:e.slice(n,o),node:null})),t}function Ja(e,t){return typeof e=="string"?Pu(e):t.generate(e,Lu)}var E={type:"Match"},O={type:"Mismatch"},pr={type:"DisallowEmpty"},Iu=40,Ou=41;function ee(e,t,r){return t===E&&r===O||e===E&&t===E&&r===E?e:(e.type==="If"&&e.else===O&&t===E&&(t=e.then,e=e.match),{type:"If",match:e,then:t,else:r})}function ts(e){return e.length>2&&e.charCodeAt(e.length-2)===Iu&&e.charCodeAt(e.length-1)===Ou}function es(e){return e.type==="Keyword"||e.type==="AtKeyword"||e.type==="Function"||e.type==="Type"&&ts(e.name)}function sn(e,t,r){switch(e){case" ":{let n=E;for(let o=t.length-1;o>=0;o--){let i=t[o];n=ee(i,n,O)}return n}case"|":{let n=O,o=null;for(let i=t.length-1;i>=0;i--){let a=t[i];if(es(a)&&(o===null&&i>0&&es(t[i-1])&&(o=Object.create(null),n=ee({type:"Enum",map:o},E,n)),o!==null)){let l=(ts(a.name)?a.name.slice(0,-1):a.name).toLowerCase();if(!(l in o)){o[l]=a;continue}}o=null,n=ee(a,E,n)}return n}case"&&":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!0};let n=O;for(let o=t.length-1;o>=0;o--){let i=t[o],a;t.length>1?a=sn(e,t.filter(function(l){return l!==i}),!1):a=E,n=ee(i,a,n)}return n}case"||":{if(t.length>5)return{type:"MatchOnce",terms:t,all:!1};let n=r?E:O;for(let o=t.length-1;o>=0;o--){let i=t[o],a;t.length>1?a=sn(e,t.filter(function(l){return l!==i}),!0):a=E,n=ee(i,a,n)}return n}}}function Du(e){let t=E,r=ln(e.term);if(e.max===0)r=ee(r,pr,O),t=ee(r,null,O),t.then=ee(E,E,t),e.comma&&(t.then.else=ee({type:"Comma",syntax:e},t,O));else for(let n=e.min||1;n<=e.max;n++)e.comma&&t!==E&&(t=ee({type:"Comma",syntax:e},t,O)),t=ee(r,ee(E,E,t),O);if(e.min===0)t=ee(E,E,t);else for(let n=0;n=65&&o<=90&&(o=o|32),o!==n)return!1}return!0}function _u(e){return e.type!==9?!1:e.value!=="?"}function is(e){return e===null?!0:e.type===18||e.type===2||e.type===21||e.type===19||e.type===23||_u(e)}function as(e){return e===null?!0:e.type===22||e.type===20||e.type===24||e.type===9&&e.value==="/"}function Uu(e,t,r){function n(){do D++,C=DAe&&(Ae=D)}function s(){p={syntax:t.syntax,opts:t.syntax.opts||p!==null&&p.opts||null,prev:p},B={type:un,syntax:t.syntax,token:B.token,prev:B}}function u(){B.type===un?B=B.prev:B={type:ss,syntax:p.syntax,token:B.token,prev:B},p=p.prev}let p=null,h=null,m=null,y=null,T=0,N=null,C=null,D=-1,Ae=0,B={type:Nu,syntax:null,token:null,prev:null};for(n();N===null&&++Tm.tokenIndex)&&(m=y,y=!1);else if(m===null){N=Ru;break}t=m.nextState,h=m.thenStack,p=m.syntaxStack,B=m.matchStack,D=m.tokenIndex,C=DD){for(;D":"<'"+t.name+"'>"));if(y!==!1&&C!==null&&t.type==="Type"&&(t.name==="custom-ident"&&C.type===1||t.name==="length"&&C.value==="0")){y===null&&(y=i(t,m)),t=O;break}s(),t=te.match;break}case"Keyword":{let J=t.name;if(C!==null){let te=C.value;if(te.indexOf("\\")!==-1&&(te=te.replace(/\\[09].*$/,"")),cn(te,J)){c(),t=E;break}}t=O;break}case"AtKeyword":case"Function":if(C!==null&&cn(C.value,t.name)){c(),t=E;break}t=O;break;case"Token":if(C!==null&&C.value===t.value){c(),t=E;break}t=O;break;case"Comma":C!==null&&C.type===18?is(B.token)?t=O:(c(),t=as(C)?O:E):t=is(B.token)||as(C)?E:O;break;case"String":let ce="",ye=D;for(;yels,isKeyword:()=>Hu,isProperty:()=>qu,isType:()=>ju});function ls(e){function t(o){return o===null?!1:o.type==="Type"||o.type==="Property"||o.type==="Keyword"}function r(o){if(Array.isArray(o.match)){for(let i=0;ir.type==="Type"&&r.name===t)}function qu(e,t){return hn(this,e,r=>r.type==="Property"&&r.name===t)}function Hu(e){return hn(this,e,t=>t.type==="Keyword")}function hn(e,t,r){let n=ls.call(e,t);return n===null?!1:n.some(r)}function cs(e){return"node"in e?e.node:cs(e.match[0])}function us(e){return"node"in e?e.node:us(e.match[e.match.length-1])}function mn(e,t,r,n,o){function i(l){if(l.syntax!==null&&l.syntax.type===n&&l.syntax.name===o){let c=cs(l),s=us(l);e.syntax.walk(t,function(u,p,h){if(u===c){let m=new w;do{if(m.appendData(p.data),p.data===s)break;p=p.next}while(p!==null);a.push({parent:h,nodes:m})}})}Array.isArray(l.match)&&l.match.forEach(i)}let a=[];return r.matched!==null&&i(r.matched),a}var{hasOwnProperty:At}=Object.prototype;function dn(e){return typeof e=="number"&&isFinite(e)&&Math.floor(e)===e&&e>=0}function ps(e){return Boolean(e)&&dn(e.offset)&&dn(e.line)&&dn(e.column)}function Wu(e,t){return function(n,o){if(!n||n.constructor!==Object)return o(n,"Type of node should be an Object");for(let i in n){let a=!0;if(At.call(n,i)!==!1){if(i==="type")n.type!==e&&o(n,"Wrong node type `"+n.type+"`, expected `"+e+"`");else if(i==="loc"){if(n.loc===null)continue;if(n.loc&&n.loc.constructor===Object)if(typeof n.loc.source!="string")i+=".source";else if(!ps(n.loc.start))i+=".start";else if(!ps(n.loc.end))i+=".end";else continue;a=!1}else if(t.hasOwnProperty(i)){a=!1;for(let l=0;!a&&l");else if(Array.isArray(s))a.push("List");else throw new Error("Wrong value `"+s+"` in `"+e+"."+i+"` structure definition")}o[i]=a.join(" | ")}return{docs:o,check:Wu(e,n)}}function hs(e){let t={};if(e.node){for(let r in e.node)if(At.call(e.node,r)){let n=e.node[r];if(n.structure)t[r]=Yu(r,n);else throw new Error("Missed `structure` field in `"+r+"` node type definition")}}return t}var Vu=hr(rr.join(" | "));function gn(e,t,r){let n={};for(let o in e)e[o].syntax&&(n[o]=r?e[o].syntax:Ge(e[o].syntax,{compact:t}));return n}function Gu(e,t,r){let n={};for(let[o,i]of Object.entries(e))n[o]={prelude:i.prelude&&(r?i.prelude.syntax:Ge(i.prelude.syntax,{compact:t})),descriptors:i.descriptors&&gn(i.descriptors,t,r)};return n}function Ku(e){for(let t=0;t(n[o]=this.createDescriptor(r.descriptors[o],"AtruleDescriptor",o,t),n),Object.create(null)):null})}addProperty_(t,r){!r||(this.properties[t]=this.createDescriptor(r,"Property",t))}addType_(t,r){!r||(this.types[t]=this.createDescriptor(r,"Type",t))}checkAtruleName(t){if(!this.getAtrule(t))return new Ke("Unknown at-rule","@"+t)}checkAtrulePrelude(t,r){let n=this.checkAtruleName(t);if(n)return n;let o=this.getAtrule(t);if(!o.prelude&&r)return new SyntaxError("At-rule `@"+t+"` should not contain a prelude");if(o.prelude&&!r&&!Je(this,o.prelude,"",!1).matched)return new SyntaxError("At-rule `@"+t+"` should contain a prelude")}checkAtruleDescriptorName(t,r){let n=this.checkAtruleName(t);if(n)return n;let o=this.getAtrule(t),i=Z(r);if(!o.descriptors)return new SyntaxError("At-rule `@"+t+"` has no known descriptors");if(!o.descriptors[i.name]&&!o.descriptors[i.basename])return new Ke("Unknown at-rule descriptor",r)}checkPropertyName(t){if(!this.getProperty(t))return new Ke("Unknown property",t)}matchAtrulePrelude(t,r){let n=this.checkAtrulePrelude(t,r);return n?ge(null,n):Je(this,this.getAtrule(t).prelude,r||"",!1)}matchAtruleDescriptor(t,r,n){let o=this.checkAtruleDescriptorName(t,r);if(o)return ge(null,o);let i=this.getAtrule(t),a=Z(r);return Je(this,i.descriptors[a.name]||i.descriptors[a.basename],n,!1)}matchDeclaration(t){return t.type!=="Declaration"?ge(null,new Error("Not a Declaration node")):this.matchProperty(t.property,t.value)}matchProperty(t,r){if(me(t).custom)return ge(null,new Error("Lexer matching doesn't applicable for custom properties"));let n=this.checkPropertyName(t);return n?ge(null,n):Je(this,this.getProperty(t),r,!0)}matchType(t,r){let n=this.getType(t);return n?Je(this,n,r,!1):ge(null,new Ke("Unknown type",t))}match(t,r){return typeof t!="string"&&(!t||!t.type)?ge(null,new Ke("Bad syntax")):((typeof t=="string"||!t.match)&&(t=this.createDescriptor(t,"Type","anonymous")),Je(this,t,r,!1))}findValueFragments(t,r,n,o){return mn(this,r,this.matchProperty(t,r),n,o)}findDeclarationValueFragments(t,r,n){return mn(this,t.value,this.matchDeclaration(t),r,n)}findAllFragments(t,r,n){let o=[];return this.syntax.walk(t,{visit:"Declaration",enter:i=>{o.push.apply(o,this.findDeclarationValueFragments(i,r,n))}}),o}getAtrule(t,r=!0){let n=Z(t);return(n.vendor&&r?this.atrules[n.name]||this.atrules[n.basename]:this.atrules[n.name])||null}getAtrulePrelude(t,r=!0){let n=this.getAtrule(t,r);return n&&n.prelude||null}getAtruleDescriptor(t,r){return this.atrules.hasOwnProperty(t)&&this.atrules.declarators&&this.atrules[t].declarators[r]||null}getProperty(t,r=!0){let n=me(t);return(n.vendor&&r?this.properties[n.name]||this.properties[n.basename]:this.properties[n.name])||null}getType(t){return hasOwnProperty.call(this.types,t)?this.types[t]:null}validate(){function t(o,i,a,l){if(a.has(i))return a.get(i);a.set(i,!1),l.syntax!==null&&an(l.syntax,function(c){if(c.type!=="Type"&&c.type!=="Property")return;let s=c.type==="Type"?o.types:o.properties,u=c.type==="Type"?r:n;(!hasOwnProperty.call(s,c.name)||t(o,c.name,u,s[c.name]))&&a.set(i,!0)},this)}let r=new Map,n=new Map;for(let o in this.types)t(this,o,r,this.types[o]);for(let o in this.properties)t(this,o,n,this.properties[o]);return r=[...r.keys()].filter(o=>r.get(o)),n=[...n.keys()].filter(o=>n.get(o)),r.length||n.length?{types:r,properties:n}:null}dump(t,r){return{generic:this.generic,types:gn(this.types,!r,t),properties:gn(this.properties,!r,t),atrules:Gu(this.atrules,!r,t)}}toString(){return JSON.stringify(this.dump())}};var{hasOwnProperty:tt}=Object.prototype,Qu={generic:!0,types:bn,atrules:{prelude:ms,descriptors:ms},properties:bn,parseContext:$u,scope:gs,atrule:["parse"],pseudo:["parse"],node:["name","structure","parse","generate","walkContext"]};function fr(e){return e&&e.constructor===Object}function ds(e){return fr(e)?{...e}:e}function $u(e,t){return Object.assign(e,t)}function gs(e,t){for(let r in t)tt.call(t,r)&&(fr(e[r])?gs(e[r],t[r]):e[r]=ds(t[r]));return e}function fs(e,t){return typeof t=="string"&&/^\s*\|/.test(t)?typeof e=="string"?e+t:t.replace(/^\s*\|\s*/,""):t||null}function bn(e,t){if(typeof t=="string")return fs(e,t);let r={...e};for(let n in t)tt.call(t,n)&&(r[n]=fs(tt.call(e,n)?e[n]:void 0,t[n]));return r}function ms(e,t){let r=bn(e,t);return!fr(r)||Object.keys(r).length?r:null}function Et(e,t,r){for(let n in r)if(tt.call(r,n)!==!1){if(r[n]===!0)tt.call(t,n)&&(e[n]=ds(t[n]));else if(r[n]){if(typeof r[n]=="function"){let o=r[n];e[n]=o({},e[n]),e[n]=o(e[n]||{},t[n])}else if(fr(r[n])){let o={};for(let i in e[n])o[i]=Et({},e[n][i],r[n]);for(let i in t[n])o[i]=Et(o[i]||{},t[n][i],r[n]);e[n]=o}else if(Array.isArray(r[n])){let o={},i=r[n].reduce(function(a,l){return a[l]=!0,a},{});for(let[a,l]of Object.entries(e[n]||{}))o[a]={},l&&Et(o[a],l,i);for(let a in t[n])tt.call(t[n],a)&&(o[a]||(o[a]={}),t[n]&&t[n][a]&&Et(o[a],t[n][a],i));e[n]=o}}}return e}var mr=(e,t)=>Et(e,t,Qu);function bs(e){let t=Ji(e),r=Ia(e),n=Ca(e),{fromPlainObject:o,toPlainObject:i}=Aa(r),a={lexer:null,createLexer:l=>new et(l,a,a.lexer.structure),tokenize:Le,parse:t,generate:n,walk:r,find:r.find,findLast:r.findLast,findAll:r.findAll,fromPlainObject:o,toPlainObject:i,fork(l){let c=mr({},e);return bs(typeof l=="function"?l(c,Object.assign):mr(c,l))}};return a.lexer=new et({generic:!0,types:e.types,atrules:e.atrules,properties:e.properties,node:e.node},a),a}var yn=e=>bs(mr({},e));var ys={generic:!0,types:{"absolute-size":"xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large","alpha-value":"|","angle-percentage":"|","angular-color-hint":"","angular-color-stop":"&&?","angular-color-stop-list":"[ [, ]?]# , ","animateable-feature":"scroll-position|contents|",attachment:"scroll|fixed|local","attr()":"attr( ? [, ]? )","attr-matcher":"['~'|'|'|'^'|'$'|'*']? '='","attr-modifier":"i|s","attribute-selector":"'[' ']'|'[' [|] ? ']'","auto-repeat":"repeat( [auto-fill|auto-fit] , [? ]+ ? )","auto-track-list":"[? [|]]* ? [? [|]]* ?","baseline-position":"[first|last]? baseline","basic-shape":"||||","bg-image":"none|","bg-layer":"|| [/ ]?||||||||","bg-position":"[[left|center|right|top|bottom|]|[left|center|right|] [top|center|bottom|]|[center|[left|right] ?]&&[center|[top|bottom] ?]]","bg-size":"[|auto]{1,2}|cover|contain","blur()":"blur( )","blend-mode":"normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",box:"border-box|padding-box|content-box","brightness()":"brightness( )","calc()":"calc( )","calc-sum":" [['+'|'-'] ]*","calc-product":" ['*' |'/' ]*","calc-value":"|||( )","cf-final-image":"|","cf-mixing-image":"?&&","circle()":"circle( []? [at ]? )","clamp()":"clamp( #{3} )","class-selector":"'.' ","clip-source":"",color:"|||||||||currentcolor|","color-stop":"|","color-stop-angle":"{1,2}","color-stop-length":"{1,2}","color-stop-list":"[ [, ]?]# , ",combinator:"'>'|'+'|'~'|['||']","common-lig-values":"[common-ligatures|no-common-ligatures]","compat-auto":"searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button","composite-style":"clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor","compositing-operator":"add|subtract|intersect|exclude","compound-selector":"[? * [ *]*]!","compound-selector-list":"#","complex-selector":" [? ]*","complex-selector-list":"#","conic-gradient()":"conic-gradient( [from ]? [at ]? , )","contextual-alt-values":"[contextual|no-contextual]","content-distribution":"space-between|space-around|space-evenly|stretch","content-list":"[|contents||||||]+","content-position":"center|start|end|flex-start|flex-end","content-replacement":"","contrast()":"contrast( [] )",counter:"|","counter()":"counter( , ? )","counter-name":"","counter-style":"|symbols( )","counter-style-name":"","counters()":"counters( , , ? )","cross-fade()":"cross-fade( , ? )","cubic-bezier-timing-function":"ease|ease-in|ease-out|ease-in-out|cubic-bezier( , , , )","deprecated-system-color":"ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText","discretionary-lig-values":"[discretionary-ligatures|no-discretionary-ligatures]","display-box":"contents|none","display-inside":"flow|flow-root|table|flex|grid|ruby","display-internal":"table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container","display-legacy":"inline-block|inline-list-item|inline-table|inline-flex|inline-grid","display-listitem":"?&&[flow|flow-root]?&&list-item","display-outside":"block|inline|run-in","drop-shadow()":"drop-shadow( {2,3} ? )","east-asian-variant-values":"[jis78|jis83|jis90|jis04|simplified|traditional]","east-asian-width-values":"[full-width|proportional-width]","element()":"element( , [first|start|last|first-except]? )|element( )","ellipse()":"ellipse( [{2}]? [at ]? )","ending-shape":"circle|ellipse","env()":"env( , ? )","explicit-track-list":"[? ]+ ?","family-name":"|+","feature-tag-value":" [|on|off]?","feature-type":"@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation","feature-value-block":" '{' '}'","feature-value-block-list":"+","feature-value-declaration":" : + ;","feature-value-declaration-list":"","feature-value-name":"","fill-rule":"nonzero|evenodd","filter-function":"|||||||||","filter-function-list":"[|]+","final-bg-layer":"<'background-color'>|||| [/ ]?||||||||","fit-content()":"fit-content( [|] )","fixed-breadth":"","fixed-repeat":"repeat( [] , [? ]+ ? )","fixed-size":"|minmax( , )|minmax( , )","font-stretch-absolute":"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|","font-variant-css21":"[normal|small-caps]","font-weight-absolute":"normal|bold|","frequency-percentage":"|","general-enclosed":"[ )]|( )","generic-family":"serif|sans-serif|cursive|fantasy|monospace|-apple-system","generic-name":"serif|sans-serif|cursive|fantasy|monospace","geometry-box":"|fill-box|stroke-box|view-box",gradient:"||||||<-legacy-gradient>","grayscale()":"grayscale( )","grid-line":"auto||[&&?]|[span&&[||]]","historical-lig-values":"[historical-ligatures|no-historical-ligatures]","hsl()":"hsl( [/ ]? )|hsl( , , , ? )","hsla()":"hsla( [/ ]? )|hsla( , , , ? )",hue:"|","hue-rotate()":"hue-rotate( )","hwb()":"hwb( [|none] [|none] [|none] [/ [|none]]? )",image:"||||||","image()":"image( ? [? , ?]! )","image-set()":"image-set( # )","image-set-option":"[|] [||type( )]","image-src":"|","image-tags":"ltr|rtl","inflexible-breadth":"||min-content|max-content|auto","inset()":"inset( {1,4} [round <'border-radius'>]? )","invert()":"invert( )","keyframes-name":"|","keyframe-block":"# { }","keyframe-block-list":"+","keyframe-selector":"from|to|","layer()":"layer( )","layer-name":" ['.' ]*","leader()":"leader( )","leader-type":"dotted|solid|space|","length-percentage":"|","line-names":"'[' * ']'","line-name-list":"[|]+","line-style":"none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset","line-width":"|thin|medium|thick","linear-color-hint":"","linear-color-stop":" ?","linear-gradient()":"linear-gradient( [|to ]? , )","mask-layer":"|| [/ ]?||||||[|no-clip]||||","mask-position":"[|left|center|right] [|top|center|bottom]?","mask-reference":"none||","mask-source":"","masking-mode":"alpha|luminance|match-source","matrix()":"matrix( #{6} )","matrix3d()":"matrix3d( #{16} )","max()":"max( # )","media-and":" [and ]+","media-condition":"|||","media-condition-without-or":"||","media-feature":"( [||] )","media-in-parens":"( )||","media-not":"not ","media-or":" [or ]+","media-query":"|[not|only]? [and ]?","media-query-list":"#","media-type":"","mf-boolean":"","mf-name":"","mf-plain":" : ","mf-range":" ['<'|'>']? '='? | ['<'|'>']? '='? | '<' '='? '<' '='? | '>' '='? '>' '='? ","mf-value":"|||","min()":"min( # )","minmax()":"minmax( [||min-content|max-content|auto] , [|||min-content|max-content|auto] )","name-repeat":"repeat( [|auto-fill] , + )","named-color":"transparent|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|<-non-standard-color>","namespace-prefix":"","ns-prefix":"[|'*']? '|'","number-percentage":"|","numeric-figure-values":"[lining-nums|oldstyle-nums]","numeric-fraction-values":"[diagonal-fractions|stacked-fractions]","numeric-spacing-values":"[proportional-nums|tabular-nums]",nth:"|even|odd","opacity()":"opacity( [] )","overflow-position":"unsafe|safe","outline-radius":"|","page-body":"? [; ]?| ","page-margin-box":" '{' '}'","page-margin-box-type":"@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom","page-selector-list":"[#]?","page-selector":"+| *","page-size":"A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger","path()":"path( [ ,]? )","paint()":"paint( , ? )","perspective()":"perspective( )","polygon()":"polygon( ? , [ ]# )",position:"[[left|center|right]||[top|center|bottom]|[left|center|right|] [top|center|bottom|]?|[[left|right] ]&&[[top|bottom] ]]","pseudo-class-selector":"':' |':' ')'","pseudo-element-selector":"':' ","pseudo-page":": [left|right|first|blank]",quote:"open-quote|close-quote|no-open-quote|no-close-quote","radial-gradient()":"radial-gradient( [||]? [at ]? , )","relative-selector":"? ","relative-selector-list":"#","relative-size":"larger|smaller","repeat-style":"repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}","repeating-conic-gradient()":"repeating-conic-gradient( [from ]? [at ]? , )","repeating-linear-gradient()":"repeating-linear-gradient( [|to ]? , )","repeating-radial-gradient()":"repeating-radial-gradient( [||]? [at ]? , )","rgb()":"rgb( {3} [/ ]? )|rgb( {3} [/ ]? )|rgb( #{3} , ? )|rgb( #{3} , ? )","rgba()":"rgba( {3} [/ ]? )|rgba( {3} [/ ]? )|rgba( #{3} , ? )|rgba( #{3} , ? )","rotate()":"rotate( [|] )","rotate3d()":"rotate3d( , , , [|] )","rotateX()":"rotateX( [|] )","rotateY()":"rotateY( [|] )","rotateZ()":"rotateZ( [|] )","saturate()":"saturate( )","scale()":"scale( , ? )","scale3d()":"scale3d( , , )","scaleX()":"scaleX( )","scaleY()":"scaleY( )","scaleZ()":"scaleZ( )","self-position":"center|start|end|self-start|self-end|flex-start|flex-end","shape-radius":"|closest-side|farthest-side","skew()":"skew( [|] , [|]? )","skewX()":"skewX( [|] )","skewY()":"skewY( [|] )","sepia()":"sepia( )",shadow:"inset?&&{2,4}&&?","shadow-t":"[{2,3}&&?]",shape:"rect( , , , )|rect( )","shape-box":"|margin-box","side-or-corner":"[left|right]||[top|bottom]","single-animation":"