module Roda::RodaPlugins::Assets

def self.configure(app, opts = {})

for a description of the supported options.
Setup the options for the plugin. See the Assets module RDoc
def self.configure(app, opts = {})
  if app.assets_opts
    prev_opts = app.assets_opts[:orig_opts]
    orig_opts = app.assets_opts[:orig_opts].merge(opts)
    [:headers, :css_headers, :js_headers, :css_opts, :js_opts, :dependencies].each do |s|
      if prev_opts[s]
        if opts[s]
          orig_opts[s] = prev_opts[s].merge(opts[s])
        else
          orig_opts[s] = prev_opts[s].dup
        end
      end
    end
    app.opts[:assets] = orig_opts.dup
    app.opts[:assets][:orig_opts] = orig_opts
  else
    app.opts[:assets] = opts.dup
    app.opts[:assets][:orig_opts] = opts
  end
  opts = app.opts[:assets]
  opts[:path] = app.expand_path(opts[:path]||"assets").freeze
  opts[:public] = app.expand_path(opts[:public]||"public").freeze
  # Combine multiple values into a path, ignoring trailing slashes
  j = lambda do |*v|
    opts.values_at(*v).
      reject{|s| s.to_s.empty?}.
      map{|s| s.chomp('/')}.
      join('/').freeze
  end
  # Same as j, but add a trailing slash if not empty
  sj = lambda do |*v|
    s = j.call(*v)
    s.empty? ? s : (s + '/').freeze
  end
  if opts[:precompiled] && !opts[:compiled] && ::File.exist?(opts[:precompiled])
    require 'json'
    opts[:compiled] = app.send(:_precompiled_asset_metadata, opts[:precompiled])
  end
  if opts[:early_hints]
    app.plugin :early_hints
  end
  if opts[:timestamp_paths] && !opts[:timestamp_paths].is_a?(String)
    opts[:timestamp_paths] = '/'
  end
  DEFAULTS.each do |k, v|
    opts[k] = v unless opts.has_key?(k)
  end
  [
   [:compiled_path, :prefix],
   [:js_route, :js_dir],
   [:css_route, :css_dir],
   [:compiled_js_route, :compiled_js_dir],
   [:compiled_css_route, :compiled_css_dir]
  ].each do |k, v|
    opts[k]  = opts[v] unless opts.has_key?(k)
  end
  [:css_headers, :js_headers, :css_opts, :js_opts, :dependencies].each do |s|
    opts[s] ||= {} 
  end
  expanded_deps = opts[:expanded_dependencies] = {}
  opts[:dependencies].each do |file, deps|
    expanded_deps[File.expand_path(file)] = Array(deps)
  end
  if headers = opts[:headers]
    opts[:css_headers] = headers.merge(opts[:css_headers])
    opts[:js_headers]  = headers.merge(opts[:js_headers])
  end
  opts[:css_headers][RodaResponseHeaders::CONTENT_TYPE] ||= "text/css; charset=UTF-8".freeze
  opts[:js_headers][RodaResponseHeaders::CONTENT_TYPE]  ||= "application/javascript; charset=UTF-8".freeze
  [:css_headers, :js_headers, :css_opts, :js_opts, :dependencies, :expanded_dependencies].each do |s|
    opts[s].freeze
  end
  [:headers, :css, :js].each do |s|
    opts[s].freeze if opts[s]
  end
  # Used for reading/writing files
  opts[:js_path]           = sj.call(:path, :js_dir)
  opts[:css_path]          = sj.call(:path, :css_dir)
  opts[:compiled_js_path]  = j.call(:public, :compiled_path, :compiled_js_dir, :compiled_name)
  opts[:compiled_css_path] = j.call(:public, :compiled_path, :compiled_css_dir, :compiled_name)
  # Used for URLs/routes
  opts[:js_prefix]           = sj.call(:prefix, :js_route)
  opts[:css_prefix]          = sj.call(:prefix, :css_route)
  opts[:compiled_js_prefix]  = j.call(:prefix, :compiled_js_route, :compiled_name)
  opts[:compiled_css_prefix] = j.call(:prefix, :compiled_css_route, :compiled_name)
  opts[:js_suffix]           = (opts[:add_suffix] ? '.js' : '').freeze
  opts[:css_suffix]          = (opts[:add_suffix] ? '.css' : '').freeze
  opts.freeze
end

def self.load_dependencies(app, opts = OPTS)

depends on them.
Load the render, caching, and h plugins, since the assets plugin
def self.load_dependencies(app, opts = OPTS)
  app.plugin :render
  app.plugin :caching
  app.plugin :h
  if opts[:relative_paths]
    app.plugin :relative_path
  end
end