module Pagy::Frontend

def pagy_bootstrap_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_bootstrap_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
  %(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination" aria-label="pager"><div class="btn-group" role="group" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      if (p_prev = pagy.prev)
        link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
      else
        %(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
      end
  }<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
      if (p_next  = pagy.next)
        link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"'
      else
        %(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next' }</a>)
      end
  }</div></nav>)
end

def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for bootstrap: it returns the html with the series of links to the pages
def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
  html = +%(<nav#{p_id} class="pagy-bootstrap-nav" aria-label="pager"><ul class="pagination">)
  html << pagy_bootstrap_prev_html(pagy, link)
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then %(<li class="page-item">#{link.call item}</li>)
            when String  then %(<li class="page-item active">#{link.call item}</li>)
            when :gap    then %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
            end
  end
  html << pagy_bootstrap_next_html(pagy, link)
  html << %(</ul></nav>)
end

def pagy_bootstrap_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_bootstrap_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
  tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
           'link'   => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
           'active' => %(<li class="page-item active">#{mark}</li>),
           'gap'    => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
           'after'  => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
  %(<nav#{p_id} class="pagy-njs pagy-bootstrap-nav-js" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
end

def pagy_bootstrap_next_html(pagy, link)

def pagy_bootstrap_next_html(pagy, link)
  if (p_next = pagy.next)
    %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
  else
    %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
  end
end

def pagy_bootstrap_prev_html(pagy, link)

def pagy_bootstrap_prev_html(pagy, link)
  if (p_prev = pagy.prev)
    %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
  else
    %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
  end
end

def pagy_bulma_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination for Bulma: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_bulma_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input class="input" type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem; margin:0 0.3rem;">)
  %(<nav#{p_id} class="pagy-bulma-combo-nav-js" aria-label="pagination"><div class="field is-grouped is-grouped-centered" role="group" #{
     pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      if (p_prev  = pagy.prev)
        %(<p class="control">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'class="button" aria-label="previous page"'}</p>)
      else
        %(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.prev'}</a></p>)
      end
  }<div class="pagy-combo-input control level is-mobile">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
      if (p_next  = pagy.next)
        %(<p class="control">#{link.call p_next, pagy_t('pagy.nav.next'), 'class="button" aria-label="next page"'}</p>)
      else
        %(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.next'}</a></p>)
      end
  }</div></nav>)
end

def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for Bulma: it returns the html with the series of links to the pages
def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  html = +%(<nav#{p_id} class="pagy-bulma-nav pagination is-centered" aria-label="pagination">)
  html << pagy_bulma_prev_next_html(pagy, link)
  html << %(<ul class="pagination-list">)
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then %(<li>#{link.call item, item, %(class="pagination-link" aria-label="goto page #{item}") }</li>)                           # page link
            when String  then %(<li>#{link.call item, item, %(class="pagination-link is-current" aria-label="page #{item}" aria-current="page")}</li>)  # active page
            when :gap    then %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)                                            # page gap
            end
  end
  html << %(</ul></nav>)
end

def pagy_bulma_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

def pagy_bulma_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  tags = { 'before' => %(#{pagy_bulma_prev_next_html(pagy, link)}<ul class="pagination-list">),
           'link'   => %(<li>#{link.call PAGE_PLACEHOLDER, PAGE_PLACEHOLDER, %(class="pagination-link" aria-label="goto page #{PAGE_PLACEHOLDER}")}</li>),
           'active' => %(<li>#{link.call PAGE_PLACEHOLDER, PAGE_PLACEHOLDER, %(class="pagination-link is-current" aria-current="page" aria-label="page #{PAGE_PLACEHOLDER}")}</li>),
           'gap'    => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap' }</span></li>),
           'after'  => '</ul>' }
  %(<nav#{p_id} class="pagy-njs pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
end

def pagy_bulma_prev_next_html(pagy, link)

def pagy_bulma_prev_next_html(pagy, link)
  html  = if (p_prev = pagy.prev)
            link.call p_prev, pagy_t('pagy.nav.prev'), 'class="pagination-previous" aria-label="previous page"'
          else
            %(<a class="pagination-previous" disabled>#{pagy_t 'pagy.nav.prev'}</a>)
          end
  html << if (p_next = pagy.next)
            link.call p_next, pagy_t('pagy.nav.next'), 'class="pagination-next" aria-label="next page"'
          else
            %(<a class="pagination-next" disabled>#{pagy_t 'pagy.nav.next' }</a>)
          end
end

def pagy_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
  %(<nav#{p_id} class="pagy-combo-nav-js pagination" aria-label="pager" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      pagy_nav_prev_html pagy, link
  }<span class="pagy-combo-input" style="margin: 0 0.6rem;">#{
      pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
  }</span> #{
      pagy_nav_next_html pagy, link
  }</nav>)
end

def pagy_foundation_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination for Foundation: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_foundation_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input class="input-group-field cell shrink" type="number" min="1" max="#{p_pages}" value="#{p_page}" style="width: #{p_pages.to_s.length+1}rem; padding: 0 0.3rem; margin: 0 0.3rem;">)
  %(<nav#{p_id} class="pagy-foundation-combo-nav-js" aria-label="Pagination"><div class="input-group" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      if (p_prev  = pagy.prev)
        link.call p_prev, pagy_t('pagy.nav.prev'), 'style="margin-bottom: 0" aria-label="previous" class="prev button primary"'
      else
        %(<a style="margin-bottom: 0" class="prev button primary disabled" href="#">#{pagy_t 'pagy.nav.prev'}</a>)
      end
  }<span class="input-group-label">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</span>#{
      if (p_next  = pagy.next)
        link.call p_next, pagy_t('pagy.nav.next'), 'style="margin-bottom: 0" aria-label="next" class="next button primary"'
      else
        %(<a style="margin-bottom: 0" class="next button primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
      end
  }</div></nav>)
end

def pagy_foundation_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for Foundation: it returns the html with the series of links to the pages
def pagy_foundation_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  html = +%(<nav#{p_id} class="pagy-foundation-nav" aria-label="Pagination"><ul class="pagination">)
  html << pagy_foundation_prev_html(pagy, link)
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then %(<li>#{link.call item}</li>)                        # page link
            when String  then %(<li class="current">#{item}</li>)                  # active page
            when :gap    then %(<li class="ellipsis gap" aria-hidden="true"></li>) # page gap
            end
  end
  html << pagy_foundation_next_html(pagy, link)
  html << %(</ul></nav>)
end

def pagy_foundation_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination for foundation: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_foundation_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  tags = { 'before' => %(<ul class="pagination">#{pagy_foundation_prev_html pagy, link}),
           'link'   => %(<li>#{link.call PAGE_PLACEHOLDER}</li>),
           'active' => %(<li class="current">#{pagy.page}</li>),
           'gap'    => %(<li class="ellipsis gap" aria-hidden="true"></li>),
           'after'  => %(#{pagy_foundation_next_html pagy, link}</ul>) }
  %(<nav#{p_id} class="pagy-njs pagy-foundation-nav-js" aria-label="Pagination" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
end

def pagy_foundation_next_html(pagy, link)

def pagy_foundation_next_html(pagy, link)
  if (p_next = pagy.next)
    %(<li class="next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
  else
    %(<li class="next disabled">#{pagy_t 'pagy.nav.next'}</li>)
  end
end

def pagy_foundation_prev_html(pagy, link)

def pagy_foundation_prev_html(pagy, link)
  if (p_prev = pagy.prev)
    %(<li class="prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
  else
    %(<li class="prev disabled">#{pagy_t 'pagy.nav.prev' }</li>)
  end
end

def pagy_info(pagy, deprecated_item_name=nil, pagy_id: nil, item_name: nil, i18n_key: nil)

Return examples: "Displaying items 41-60 of 324 in total" of "Displaying Products 41-60 of 324 in total"
def pagy_info(pagy, deprecated_item_name=nil, pagy_id: nil, item_name: nil, i18n_key: nil)
  p_id      = %( id="#{pagy_id}") if pagy_id
  item_name = Pagy.deprecated_arg(:item_name, deprecated_item_name, :item_name, item_name) if deprecated_item_name
  p_count = pagy.count
  key     = if    p_count.zero?   then 'pagy.info.no_items'
            elsif pagy.pages == 1 then 'pagy.info.single_page'
            else                       'pagy.info.multiple_pages'
            end
  %(<span#{p_id} class="pagy-info">#{
  pagy_t key, item_name: item_name || pagy_t(i18n_key || pagy.vars[:i18n_key], count: p_count),
              count: p_count, from: pagy.from, to: pagy.to
  }</span>)
end

def pagy_items_selector_js(pagy, deprecated_id=nil, pagy_id: nil, item_name: nil, i18n_key: nil, link_extra: '')

Return the items selector HTML. For example "Show [20] items per page"
def pagy_items_selector_js(pagy, deprecated_id=nil, pagy_id: nil, item_name: nil, i18n_key: nil, link_extra: '')
  return '' unless pagy.vars[:enable_items_extra]
  pagy_id        = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id           = %( id="#{pagy_id}") if pagy_id
  p_vars         = pagy.vars
  p_items        = p_vars[:items]
  p_vars[:items] = ITEMS_PLACEHOLDER
  link           = pagy_marked_link(pagy_link_proc(pagy, link_extra: link_extra))
  p_vars[:items] = p_items # restore the items
  html  = %(<span#{p_id} class="pagy-items-selector-js" #{pagy_json_attr pagy, :items_selector, pagy.from, link}>)
  input = %(<input type="number" min="1" max="#{p_vars[:max_items]}" value="#{p_items}" style="padding: 0; text-align: center; width: #{p_items.to_s.length+1}rem;">)
  html << pagy_t('pagy.items_selector_js', item_name:   item_name || pagy_t(i18n_key || p_vars[:i18n_key], count: p_items),
                                           items_input: input,
                                           count:       p_items)
  html << %(</span>)
end

def pagy_json_attr(pagy, *args)

it returns a script tag with the JSON-serialized args generated with the faster oj gem
def pagy_json_attr(pagy, *args)
  args << pagy.vars[:page_param] if pagy.vars[:enable_trim_extra]
  %(data-pagy-json="#{Oj.dump(args, mode: :strict).gsub('"', '&quot;')}")
end

def pagy_json_attr(pagy, *args)

it returns a script tag with the JSON-serialized args generated with the slower to_json
def pagy_json_attr(pagy, *args)
  args << pagy.vars[:page_param] if pagy.vars[:enable_trim_extra]
  %(data-pagy-json="#{args.to_json.gsub('"', '&quot;')}")
end

def pagy_link_proc(pagy, deprecated_link_extra=nil, link_extra: '')

Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
Returns a performance optimized proc to generate the HTML links
def pagy_link_proc(pagy, deprecated_link_extra=nil, link_extra: '')
  link_extra = Pagy.deprecated_arg(:link_extra, deprecated_link_extra, :link_extra, link_extra) if deprecated_link_extra
  p_prev = pagy.prev
  p_next = pagy.next
  left, right = %(<a href="#{pagy_url_for pagy, PAGE_PLACEHOLDER}" #{pagy.vars[:link_extra]} #{link_extra}).split(PAGE_PLACEHOLDER, 2)
  lambda do |num, text=num, extra_attrs=''|
    %(#{left}#{num}#{right}#{ case num
                              when p_prev then ' rel="prev"'
                              when p_next then ' rel="next"'
                              else             ''
                              end } #{extra_attrs}>#{text}</a>)
  end
end

def pagy_marked_link(link)

it returns the marked link to used by pagy.js
def pagy_marked_link(link)
  link.call PAGE_PLACEHOLDER, '', 'style="display: none;"'
end

def pagy_materialize_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination for materialize: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_materialize_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  style   = ' style="vertical-align: middle;"'
  input   = %(<input type="number" class="browser-default" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 2px; border: none; border-radius: 2px; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
  %(<div#{p_id} class="pagy-materialize-combo-nav-js pagination" role="navigation" aria-label="pager"><div class="pagy-compact-chip" role="group" style="height: 35px; border-radius: 18px; background: #e4e4e4; display: inline-block;"><ul class="pagination" style="margin: 0" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      pagy_materialize_prev_html pagy, link, style
  }<div class="pagy-combo-input btn-flat" style="cursor: default; padding: 0px">#{
      pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
  }</div>#{
      pagy_materialize_next_html pagy, link, style
  }</ul></div>)
end

def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for materialize: it returns the html with the series of links to the pages
def pagy_materialize_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  html = +%(<div#{p_id} class="pagy-materialize-nav pagination" role="navigation" aria-label="pager"><ul class="pagination">)
  html << pagy_materialize_prev_html(pagy, link)
  pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then %(<li class="waves-effect">#{link.call item}</li>)                           # page link
            when String  then %(<li class="active">#{link.call item}</li>)                                 # active page
            when :gap    then %(<li class="gap disabled"><a href="#">#{pagy_t 'pagy.nav.gap'}</a></li>)    # page gap
            end
  end
  html << pagy_materialize_next_html(pagy, link)
  html << %(</ul></div>)
end

def pagy_materialize_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination for materialize: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_materialize_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  tags = { 'before' => %(<ul class="pagination">#{pagy_materialize_prev_html pagy, link}),
           'link'   => %(<li class="waves-effect">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
           'active' => %(<li class="active">#{mark}</li>),
           'gap'    => %(<li class="gap disabled"><a href="#">#{pagy_t 'pagy.nav.gap'}</a></li>),
           'after'  => %(#{pagy_materialize_next_html pagy, link}</ul>) }
  %(<div#{p_id} class="pagy-njs pagy-materialize-nav-js" role="navigation" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></div>)
end

def pagy_materialize_next_html(pagy, link, style='')

def pagy_materialize_next_html(pagy, link, style='')
  if (p_next = pagy.next)
    %(<li class="waves-effect next"#{style}>#{link.call p_next, '<i class="material-icons">chevron_right</i>', 'aria-label="next"'}</li>)
  else
    %(<li class="next disabled"#{style}><a href="#"><i class="material-icons">chevron_right</i></a></li>)
  end
end

def pagy_materialize_prev_html(pagy, link, style='')

def pagy_materialize_prev_html(pagy, link, style='')
  if (p_prev = pagy.prev)
    %(<li class="waves-effect prev"#{style}>#{link.call p_prev, '<i class="material-icons">chevron_left</i>', 'aria-label="previous"'}</li>)
  else
    %(<li class="prev disabled"#{style}><a href="#"><i class="material-icons">chevron_left</i></a></li>)
  end
end

def pagy_nav(pagy, pagy_id: nil, link_extra: '')

Generic pagination: it returns the html with the series of links to the pages
def pagy_nav(pagy, pagy_id: nil, link_extra: '')
  p_id   = %( id="#{pagy_id}") if pagy_id
  link   = pagy_link_proc(pagy, link_extra: link_extra)
  p_prev = pagy.prev
  p_next = pagy.next
  html  = +%(<nav#{p_id} class="pagy-nav pagination" aria-label="pager">)
  html << if p_prev
            %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
          else
            %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev')}</span> )
          end
  pagy.series.each do |item|  # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then %(<span class="page">#{link.call item}</span> )               # page link
            when String  then %(<span class="page active">#{item}</span> )                  # current page
            when :gap    then %(<span class="page gap">#{pagy_t('pagy.nav.gap')}</span> )   # page gap
            end
  end
  html << if p_next
            %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
          else
            %(<span class="page next disabled">#{pagy_t('pagy.nav.next')}</span>)
          end
  html << %(</nav>)
end

def pagy_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  tags = { 'before' => pagy_nav_prev_html(pagy, link),
           'link'   => %(<span class="page">#{link.call(PAGE_PLACEHOLDER)}</span> ),
           'active' => %(<span class="page active">#{pagy.page}</span> ),
           'gap'    => %(<span class="page gap">#{pagy_t 'pagy.nav.gap'}</span> ),
           'after'  => pagy_nav_next_html(pagy, link) }
  %(<nav#{p_id} class="pagy-njs pagy-nav-js pagination" aria-label="pager" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
end

def pagy_nav_next_html(pagy, link)

def pagy_nav_next_html(pagy, link)
  if (p_next = pagy.next)
    %(<span class="page next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</span>)
  else
    %(<span class="page next disabled">#{pagy_t 'pagy.nav.next'}</span>)
  end
end

def pagy_nav_prev_html(pagy, link)

def pagy_nav_prev_html(pagy, link)
  if (p_prev = pagy.prev)
    %(<span class="page prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</span> )
  else
    %(<span class="page prev disabled">#{pagy_t 'pagy.nav.prev'}</span> )
  end
end

def pagy_next_link(pagy, deprecated_text=nil, deprecated_link_extra=nil, text: pagy_t('pagy.nav.next'), link_extra: '')

def pagy_next_link(pagy, deprecated_text=nil, deprecated_link_extra=nil, text: pagy_t('pagy.nav.next'), link_extra: '')
  text       = Pagy.deprecated_arg(:text, deprecated_text, :text, text) if deprecated_text
  link_extra = Pagy.deprecated_arg(:link_extra, deprecated_link_extra, :link_extra, link_extra) if deprecated_link_extra
  if pagy.next
    %(<span class="page next"><a href="#{pagy_url_for(pagy, pagy.next)}" rel="next" aria-label="next" #{pagy.vars[:link_extra]} #{link_extra}>#{text}</a></span>)
  else
    %(<span class="page next disabled">#{text}</span>)
  end
end

def pagy_next_link_tag(pagy)

def pagy_next_link_tag(pagy)
  %(<link href="#{pagy_url_for(pagy, pagy.next)}" rel="next"/>) if pagy.next
end

def pagy_next_url(pagy)

def pagy_next_url(pagy)
  pagy_url_for(pagy, pagy.next) if pagy.next
end

def pagy_prev_link(pagy, deprecated_text=nil, deprecated_link_extra=nil, text: pagy_t('pagy.nav.prev'), link_extra: '')

def pagy_prev_link(pagy, deprecated_text=nil, deprecated_link_extra=nil, text: pagy_t('pagy.nav.prev'), link_extra: '')
  text       = Pagy.deprecated_arg(:text, deprecated_text, :text, text) if deprecated_text
  link_extra = Pagy.deprecated_arg(:link_extra, deprecated_link_extra, :link_extra, link_extra) if deprecated_link_extra
  if pagy.prev
    %(<span class="page prev"><a href="#{pagy_url_for(pagy, pagy.prev)}" rel="prev" aria-label="previous" #{pagy.vars[:link_extra]} #{link_extra}>#{text}</a></span>)
  else
    %(<span class="page prev disabled">#{text}</span>)
  end
end

def pagy_prev_link_tag(pagy)

def pagy_prev_link_tag(pagy)
  %(<link href="#{pagy_url_for(pagy, pagy.prev)}" rel="prev"/>) if pagy.prev
end

def pagy_prev_url(pagy)

def pagy_prev_url(pagy)
  pagy_url_for(pagy, pagy.prev) if pagy.prev
end

def pagy_semantic_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Combo pagination for semantic: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_semantic_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem; margin: 0 0.3rem">)
  %(<div#{p_id} class="pagy-semantic-combo-nav-js ui compact menu" role="navigation" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
     pagy_semantic_prev_html pagy, link
  }<div class="pagy-combo-input item">#{
     pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
  }</div> #{
     pagy_semantic_next_html pagy, link
  }</div>)
end

def pagy_semantic_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for semantic: it returns the html with the series of links to the pages
def pagy_semantic_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
  html = +%(<div#{p_id} class="pagy-semantic-nav ui pagination menu">)
  html << pagy_semantic_prev_html(pagy, link)
  pagy.series.each do |item|  # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
    html << case item
            when Integer then link.call item                                                 # page link
            when String  then %(<a class="item active">#{item}</a>)                          # current page
            when :gap    then %(<div class="disabled item">#{pagy_t 'pagy.nav.gap'}</div>)   # page gap
            end
  end
  html << pagy_semantic_next_html(pagy, link)
  html << %(</div>)
end

def pagy_semantic_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination for semantic: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_semantic_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: %(class="item" #{link_extra}))
  tags = { 'before' => pagy_semantic_prev_html(pagy, link),
           'link'   => link.call(PAGE_PLACEHOLDER),
           'active' => %(<a class="item active">#{pagy.page}</a>),
           'gap'    => %(<div class="disabled item">#{pagy_t('pagy.nav.gap')}</div>),
           'after'  => pagy_semantic_next_html(pagy, link) }
  %(<div#{p_id} class="pagy-njs pagy-semantic-nav-js ui pagination menu" role="navigation" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></div>)
end

def pagy_semantic_next_html(pagy, link)

def pagy_semantic_next_html(pagy, link)
  if (p_next = pagy.next)
    link.call p_next, '<i class="right small chevron icon"></i>', 'aria-label="next"'
  else
    +%(<div class="item disabled"><i class="right small chevron icon"></i></div>)
  end
end

def pagy_semantic_prev_html(pagy, link)

def pagy_semantic_prev_html(pagy, link)
  if (p_prev = pagy.prev)
    link.call p_prev, '<i class="left small chevron icon"></i>', 'aria-label="previous"'
  else
    +%(<div class="item disabled"><i class="left small chevron icon"></i></div>)
  end
end

def pagy_t(key, **opts)

(@pagy_locale explicitly initialized in order to avoid warning)
Similar to I18n.t: just ~18x faster using ~10x less memory
def pagy_t(key, **opts)
  Pagy::I18n.t @pagy_locale||=nil, key, **opts
end

def pagy_uikit_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')

Javascript combo pagination for uikit: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
def pagy_uikit_combo_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '')
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id    = %( id="#{pagy_id}") if pagy_id
  link    = pagy_link_proc(pagy, link_extra: link_extra)
  p_page  = pagy.page
  p_pages = pagy.pages
  input   = %(<input type="number" min="1" max="#{p_pages}" value="#{p_page}" class="uk-input" style="padding: 0; text-align: center; width: #{p_pages.to_s.length+1}rem;">)
  %(<div#{p_id} class="pagy-uikit-combo-nav-js uk-button-group" #{
      pagy_json_attr pagy, :combo_nav, p_page, pagy_marked_link(link)
  }>#{
      if (p_prev = pagy.prev)
        link.call p_prev, pagy_t('pagy.nav.prev'), 'class="uk-button uk-button-default"'
      else
        %(<button class="uk-button uk-button-default" disabled>#{pagy_t 'pagy.nav.prev'}</button>)
      end
  }<div class="uk-text-middle uk-margin-left uk-margin-right">#{
      pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages
  }</div>#{
      if (p_next = pagy.next)
        link.call p_next, pagy_t('pagy.nav.next'), 'class="uk-button uk-button-default"'
      else
        %(<button class="uk-button uk-button-default" disabled>#{pagy_t 'pagy.nav.next'}</button>)
      end
  }</div>)
end

def pagy_uikit_nav(pagy, pagy_id: nil, link_extra: '')

Pagination for uikit: it returns the html with the series of links to the pages
def pagy_uikit_nav(pagy, pagy_id: nil, link_extra: '')
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  html = %(<ul#{p_id} class="pagy-uikit-nav uk-pagination uk-flex-center">#{pagy_uikit_prev_html pagy, link})
  pagy.series.each do |item|
    html << case    item
            when Integer then %(<li>#{link.call item}</li>)
            when String  then %(<li class="uk-active"><span>#{item}</span></li>)
            when :gap    then %(<li class="uk-disabled"><span>#{pagy_t 'pagy.nav.gap'}</span></li>)
            end
  end
  html << pagy_uikit_next_html(pagy, link)
  html << %(</ul>)
end

def pagy_uikit_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)

Javascript pagination for uikit: it returns a nav and a JSON tag used by the Pagy.nav javascript
def pagy_uikit_nav_js(pagy, deprecated_id=nil, pagy_id: nil, link_extra: '', steps: nil)
  pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
  p_id = %( id="#{pagy_id}") if pagy_id
  link = pagy_link_proc(pagy, link_extra: link_extra)
  tags = { 'before' => pagy_uikit_prev_html(pagy, link),
           'link'   => %(<li>#{link.call(PAGE_PLACEHOLDER)}</li>),
           'active' => %(<li class="uk-active"><span>#{PAGE_PLACEHOLDER}</span></li>),
           'gap'    => %(<li class="uk-disabled"><span>#{pagy_t 'pagy.nav.gap'}</span></li>),
           'after'  => pagy_uikit_next_html(pagy, link) }
  %(<ul#{p_id} class="pagy-njs pagy-uikit-nav-js uk-pagination uk-flex-center" #{pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></ul>)
end

def pagy_uikit_next_html(pagy, link)

def pagy_uikit_next_html(pagy, link)
  next_span = %(<span uk-pagination-next>#{pagy_t 'pagy.nav.next'}</span>)
  if (p_next = pagy.next)
    %(<li>#{link.call p_next, next_span}</li>)
  else
    %(<li class="uk-disabled"><a href="#">#{next_span}</a></li>)
  end
end

def pagy_uikit_prev_html(pagy, link)

def pagy_uikit_prev_html(pagy, link)
  previous_span = %(<span uk-pagination-previous>#{pagy_t 'pagy.nav.prev'}</span>)
  if (p_prev = pagy.prev)
    %(<li>#{link.call p_prev, previous_span}</li>)
  else
    %(<li class="uk-disabled"><a href="#">#{previous_span}</a></li>)
  end
end