text: import os
  
  import django_countries.widgets
  import htmlgenerator as hg
  from _strptime import TimeRE
  from django.conf import settings
  from django.forms import widgets
  from django.utils import formats
  from django.utils.translation import gettext_lazy as _
  from phonenumber_field.formfields import PhoneNumberField
  
  from ..button import Button
  from ..icon import Icon
  from ..tag import Tag
  from .helpers import REQUIRED_LABEL, Label, to_php_formatstr
  
  # Missing widget implementations:
  # DateTimeInput
  # RadioSelect
  
  
  # A plain, largely unstyled input element
  # It provides the basic structure for fields used
  # in bread forms
  class BaseWidget(hg.DIV):
      # used to mark that this class can be used in place of the according django widget or field
      # all bread widgets must have this if they should be used automatically to render form fields
      django_widget = None
  
      # default attributes which are used to create the input element in a standardized way for many inputs
      carbon_input_class = ""
      carbon_input_error_class = ""
      input_type = None
  
      # __init__ of derived classes should support the following parameters
      # label: bread.layout.components.forms.utils.Label
      # help_text: Optional[Any]
      # errors: bread.layout.components.forms.utils.ErrorList
      #         ``hg.If(getattr(errors, "condition", None), ...`` can be used
      #         to render parts depending if there are errors
      # inputelement_attrs: Union[Lazy[dict], dict],
      # boundfield: Optional[django.forms.BoundField],
  
      def __init__(self, *args, **kwargs):
          # prevent rendering of any of the special kwargs we use in generate_formfield
          for param in [
              "label_element",
              "label",
              "help_text_element",
              "error_element",
              "inputelement_attrs",
              "boundfield",
          ]:
              if param in kwargs:
                  raise Exception(
                      f"Widget {type(self)} tries to render parameter {param}"
                  )
          super().__init__(*args, **kwargs)
  
      def get_input_element(self, inputelement_attrs, errors, **kwargs):
          return hg.INPUT(
              type=self.input_type,
              lazy_attributes=_combine_lazy_dict(
                  _append_classes(
                      inputelement_attrs or {},
                      self.carbon_input_class,
                      hg.If(
                          getattr(errors, "condition", False),
                          self.carbon_input_error_class,
                      ),
                  ),
                  kwargs,
              ),
              data_invalid=hg.If(getattr(errors, "condition", False), True),
          )
  
      def with_fieldwrapper(self):
          return hg.DIV(self, _class="bx--form-item")
  
  
  class HiddenInput(BaseWidget):
      django_widget = widgets.HiddenInput
      input_type = "hidden"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          super().__init__(self.get_input_element(inputelement_attrs, errors))
  
  
  class TextInput(BaseWidget):
      django_widget = widgets.TextInput
      carbon_input_class = "bx--text-input"
      carbon_input_error_class = "bx--text-input--invalid"
      input_type = "text"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          icon=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              label,
              hg.DIV(
                  hg.If(
                      errors.condition,
                      Icon(
                          "warning--filled",
                          size=16,
                          _class="bx--text-input__invalid-icon",
                      ),
                  ),
                  self.get_input_element(inputelement_attrs, errors),
                  hg.If(
                      icon,
                      hg.If(
                          hg.F(lambda c: isinstance(icon, str)),
                          Icon(
                              icon,
                              size=16,
                              _class="text-input-icon",
                          ),
                          icon,
                      ),
                  ),
                  _class=(
                      "bx--text-input__field-wrapper"
                      + (" text-input-with-icon" if icon is not None else "")
                  ),
                  data_invalid=hg.If(errors.condition, True),
              ),
              errors,
              help_text,
              **hg.merge_html_attrs(attributes, {"_class": "bx--text-input-wrapper"}),
          )
  
  
  class PhoneNumberInput(TextInput):
      input_type = "tel"
      django_widget = PhoneNumberField
  
      def __init__(self, *args, **attributes):
          super().__init__(*args, icon="phone", **attributes)
  
  
  class UrlInput(TextInput):
      django_widget = widgets.URLInput
      input_type = "url"
  
      def __init__(self, *args, **attributes):
          super().__init__(*args, icon="link", **attributes)
  
  
  class EmailInput(TextInput):
      django_widget = widgets.EmailInput
      input_type = "email"
  
      def __init__(self, *args, **attributes):
          super().__init__(*args, icon="email", **attributes)
  
  
  class NumberInput(BaseWidget):
      django_widget = widgets.NumberInput
      input_type = "number"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              label,
              hg.DIV(
                  self.get_input_element(inputelement_attrs, errors),
                  hg.DIV(
                      hg.BUTTON(
                          Icon("caret--up", size=16),
                          _class="bx--number__control-btn up-icon",
                          type="button",
                      ),
                      hg.BUTTON(
                          Icon("caret--down", size=16),
                          _class="bx--number__control-btn down-icon",
                          type="button",
                      ),
                      _class="bx--number__controls",
                  ),
                  _class="bx--number__input-wrapper",
              ),
              errors,
              help_text,
              data_numberinput=True,
              data_invalid=hg.If(errors.condition, True),
              **hg.merge_html_attrs(attributes, {"_class": "bx--number"}),
          )
  
  
  class TimeInput(TextInput):
      django_widget = widgets.TimeInput
      input_type = "time"
  
  
  class PasswordInput(TextInput):
      django_widget = widgets.PasswordInput
      carbon_input_class = "bx--password-input bx--text-input"
      carbon_input_error_class = "bx--text-input--invalid"
      input_type = "password"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          showhidebtn = Button(
              _("Show password"),
              icon=hg.BaseElement(
                  Icon("view--off", _class="bx--icon--visibility-off", hidden="true"),
                  Icon("view", _class="bx--icon--visibility-on"),
              ),
              notext=True,
          )
          # override attributes from button
          showhidebtn.attributes["_class"] = (
              "bx--text-input--password__visibility__toggle bx--tooltip__trigger "
              "bx--tooltip--a11y bx--tooltip--bottom bx--tooltip--align-center"
          )
          super().__init__(
              label=label,
              help_text=help_text,
              errors=errors,
              inputelement_attrs=_combine_lazy_dict(
                  inputelement_attrs, {"data_toggle_password_visibility": True}
              ),
              icon=showhidebtn,
              **hg.merge_html_attrs(
                  attributes,
                  {"data_text_input": True, "_class": "bx--password-input-wrapper"},
              ),
          )
  
  
  class Textarea(BaseWidget):
      django_widget = widgets.Textarea
      carbon_input_class = "bx--text-area bx--text-area--v2"
      carbon_input_error_class = "bx--text-area--invalid"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              label,
              hg.DIV(
                  hg.If(
                      getattr(errors, "condition", None),
                      Icon(
                          "warning--filled",
                          size=16,
                          _class="bx--text-area__invalid-icon",
                      ),
                  ),
                  hg.TEXTAREA(
                      boundfield.value() if boundfield else None,
                      lazy_attributes=_combine_lazy_dict(
                          _append_classes(
                              inputelement_attrs or {},
                              self.carbon_input_class,
                              hg.If(
                                  getattr(errors, "condition", None),
                                  self.carbon_input_error_class,
                              ),
                          ),
                          {"value": None},
                      ),
                  ),
                  _class="bx--text-area__wrapper",
                  data_invalid=hg.If(getattr(errors, "condition", None), True),
              ),
              help_text,
              errors,
              **attributes,
          )
  
  
  class Select(BaseWidget):
      django_widget = widgets.Select
      carbon_input_class = "bx--select-input"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          inline=False,
          choices=None,  # for non-django-form select elements use this
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          select_wrapper = hg.DIV(
              hg.SELECT(
                  hg.Iterator(
                      _optgroups_from_choices(
                          choices,
                          name=inputelement_attrs.get("name"),
                          value=inputelement_attrs.get("value"),
                      )
                      if choices
                      else _gen_optgroup(boundfield),
                      "optgroup",
                      hg.If(
                          hg.C("optgroup.0"),
                          hg.OPTGROUP(
                              hg.Iterator(
                                  hg.C("optgroup.1"),
                                  "option",
                                  hg.OPTION(
                                      hg.C("option.label"),
                                      _class="bx--select-option",
                                      value=hg.C("option.value"),
                                      lazy_attributes=hg.C("option.attrs"),
                                  ),
                              ),
                              _class="bx--select-optgroup",
                              label=hg.C("optgroup.0"),
                          ),
                          hg.Iterator(
                              hg.C("optgroup.1"),
                              "option",
                              hg.OPTION(
                                  hg.C("option.label"),
                                  _class="bx--select-option",
                                  value=hg.C("option.value"),
                                  lazy_attributes=hg.C("option.attrs"),
                              ),
                          ),
                      ),
                  ),
                  lazy_attributes=_append_classes(
                      inputelement_attrs,
                      self.carbon_input_class,
                      hg.If(
                          getattr(errors, "condition", None),
                          self.carbon_input_error_class,
                      ),
                  ),
              ),
              Icon(
                  "chevron--down",
                  size=16,
                  _class="bx--select__arrow",
                  aria_hidden="true",
              ),
              hg.If(
                  getattr(errors, "condition", None),
                  Icon(
                      "warning--filled",
                      size=16,
                      _class="bx--select__invalid-icon",
                  ),
              ),
              _class="bx--select-input__wrapper",
              data_invalid=hg.If(getattr(errors, "condition", None), True),
          )
          super().__init__(
              label,
              hg.If(
                  inline,
                  hg.DIV(
                      select_wrapper,
                      errors,
                      _class="bx--select-input--inline__wrapper",
                  ),
                  select_wrapper,
              ),
              help_text,
              hg.If(inline, None, errors),  # not displayed if this is inline
              **hg.merge_html_attrs(
                  attributes,
                  {
                      "_class": hg.BaseElement(
                          "bx--select",
                          hg.If(inline, " bx--select--inline"),
                          hg.If(
                              getattr(errors, "condition", None), " bx--select--invalid"
                          ),
                          hg.If(
                              inputelement_attrs.get("disabled"),
                              " bx--select--disabled",
                          ),
                      ),
                  },
              ),
          )
  
  
  class NullBooleanSelect(Select):
      django_widget = widgets.NullBooleanSelect
  
  
  class SelectMultiple(BaseWidget):
      django_widget = widgets.SelectMultiple
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,  # for django-form select elements use this
          choices=None,  # for non-django-form select elements use this
          **attributes,  # for non-django-form select elements use this
      ):
          inputelement_attrs = inputelement_attrs or {}
          optgroups = (
              _optgroups_from_choices(
                  choices,
                  name=inputelement_attrs.get("name"),
                  value=inputelement_attrs.get("value"),
              )
              if choices
              else _gen_optgroup(boundfield)
          )
  
          def countselected(context):
              options = [o for og in hg.resolve_lazy(optgroups, context) for o in og[1]]
              return len([o for o in options if o and o["selected"]])
  
          searchfieldid = hg.html_id(self)
          super().__init__(
              label,
              hg.If(
                  inputelement_attrs.get("disabled"),
                  hg.DIV(
                      hg.Iterator(
                          optgroups,
                          "optiongroup",
                          hg.Iterator(
                              hg.C("optiongroup.1"),
                              "option",
                              hg.If(hg.C("option.selected"), Tag(hg.C("option.label"))),
                          ),
                      )
                  ),
                  hg.DIV(
                      hg.DIV(
                          hg.DIV(
                              hg.F(countselected),
                              Icon(
                                  "close",
                                  focusable="false",
                                  size=15,
                                  role="img",
                                  onclick="clearMultiselect(this.parentElement.parentElement.parentElement)",
                              ),
                              role="button",
                              _class="bx--list-box__selection bx--list-box__selection--multi bx--tag--filter",
                              tabindex="0",
                              title="Clear all selected items",
                          ),
                          hg.INPUT(
                              id=searchfieldid,
                              _class="bx--text-input",
                              placeholder="Filter...",
                              onclick="this.parentElement.nextElementSibling.style.display = 'block'",
                              onkeyup="filterOptions(this.parentElement.parentElement)",
                          ),
                          hg.DIV(
                              Icon(
                                  "chevron--down", size=16, role="img", focusable="false"
                              ),
                              _class="bx--list-box__menu-icon",
                              onclick="this.parentElement.nextElementSibling.style.display = this.parentElement.nextElementSibling.style.display == 'none' ? 'block' : 'none';",
                          ),
                          role="button",
                          _class="bx--list-box__field",
                          tabindex="0",
                          onload="window.addEventListener('click', (e) => {this.nextElementSibling.style.display = 'none'})",
                      ),
                      hg.FIELDSET(
                          hg.Iterator(
                              optgroups,
                              "optgroup",
                              hg.Iterator(
                                  hg.C("optgroup.1"),
                                  "option",
                                  hg.DIV(
                                      hg.DIV(
                                          hg.DIV(
                                              hg.LABEL(
                                                  hg.INPUT(
                                                      type="checkbox",
                                                      readonly=True,
                                                      _class="bx--checkbox",
                                                      value=hg.C("option.value"),
                                                      lazy_attributes=hg.C(
                                                          "option.attrs"
                                                      ),
                                                      onchange="updateMultiselect(this.closest('.bx--multi-select'))",
                                                      checked=hg.C("option.selected"),
                                                      name=hg.C("option.name"),
                                                  ),
                                                  hg.SPAN(
                                                      _class="bx--checkbox-appearance"
                                                  ),
                                                  hg.SPAN(
                                                      hg.C("option.label"),
                                                      _class="bx--checkbox-label-text",
                                                  ),
                                                  title=hg.C("option.label"),
                                                  _class="bx--checkbox-label",
                                              ),
                                              _class="bx--form-item bx--checkbox-wrapper",
                                          ),
                                          _class="bx--list-box__menu-item__option",
                                      ),
                                      _class="bx--list-box__menu-item",
                                  ),
                              ),
                          ),
                          _class="bx--list-box__menu",
                          role="listbox",
                          style="display: none",
                      ),
                      _class=hg.BaseElement(
                          "bx--multi-select bx--list-box bx--multi-select--selected bx--combo-box bx--multi-select--filterable",
                          hg.If(
                              inputelement_attrs.get("disabled"),
                              " bx--list-box--disabled",
                          ),
                      ),
                      data_invalid=hg.If(getattr(errors, "condition", None), True),
                  ),
              ),
              help_text,
              errors,
              **hg.merge_html_attrs(
                  attributes,
                  {
                      "onclick": "event.stopPropagation()",
                      "_class": "bx--list-box__wrapper",
                  },
              ),
          )
  
  
  class Checkbox(BaseWidget):
      django_widget = widgets.CheckboxInput
      carbon_input_class = "bx--checkbox"
      input_type = "checkbox"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          attrs = {}
          if boundfield:
              attrs["checked"] = hg.F(
                  lambda c: hg.resolve_lazy(boundfield, c).field.widget.check_test(
                      hg.resolve_lazy(boundfield, c).value()
                  )
              )
              attrs["value"] = None
          inputelement_attrs = _combine_lazy_dict(inputelement_attrs, attrs)
          # labels for checkboxes are treated a bit different, need to use plain value
          label = hg.F(
              lambda c, label=label: getattr(hg.resolve_lazy(label, c), "label", label)
          )
          required = hg.F(lambda c, label=label: hg.resolve_lazy(label, c) is not None)
          super().__init__(
              hg.LABEL(
                  self.get_input_element(inputelement_attrs, errors),
                  label,
                  hg.If(
                      inputelement_attrs.get("required"), hg.If(required, REQUIRED_LABEL)
                  ),
                  _class=hg.BaseElement(
                      "bx--checkbox-label",
                      hg.If(inputelement_attrs.get("disabled"), " bx--label--disabled"),
                  ),
                  data_contained_checkbox_state=hg.If(
                      inputelement_attrs.get("checked"),
                      "true",
                      "false",
                  ),
                  data_invalid=hg.If(getattr(errors, "condition", False), True),
              ),
              help_text,
              errors,
              **hg.merge_html_attrs(attributes, {"_class": "bx--checkbox-wrapper"}),
          )
  
  
  class CheckboxSelectMultiple(BaseWidget):
      django_widget = widgets.CheckboxSelectMultiple
      carbon_input_class = "bx--checkbox"
      input_type = "checkbox"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              hg.FIELDSET(
                  label,
                  hg.Iterator(
                      boundfield.subwidgets,
                      "checkbox",
                      Checkbox(
                          label=Label(hg.C("checkbox").data["label"]),
                          inputelement_attrs=_combine_lazy_dict(
                              _combine_lazy_dict(
                                  inputelement_attrs,
                                  {
                                      "name": hg.C("checkbox").data["name"],
                                      "value": hg.C("checkbox").data["value"],
                                      "checked": hg.C("checkbox").data["selected"],
                                  },
                              ),
                              hg.C("checkbox").data["attrs"],
                          ),
                      ),
                  ),
                  data_invalid=hg.If(getattr(errors, "condition", False), True),
              ),
              help_text,
              errors,
              **attributes,
          )
  
  
  class RadioButton(BaseWidget):
      django_widget = None  # only used inside RadioSelect
      carbon_input_class = "bx--radio-button"
      input_type = "radio"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          attrs = {}
          if boundfield:
              attrs["checked"] = hg.F(
                  lambda c: hg.resolve_lazy(boundfield, c).field.widget.check_test(
                      hg.resolve_lazy(boundfield, c).value()
                  )
              )
          inputelement_attrs = _combine_lazy_dict(inputelement_attrs, attrs)
          label = None if label is None else label.label
          super().__init__(
              self.get_input_element(inputelement_attrs, errors),
              hg.LABEL(
                  hg.SPAN(_class="bx--radio-button__appearance"),
                  hg.SPAN(label, _class="bx--radio-button__label-text"),
                  _class="bx--radio-button__label",
                  _for=inputelement_attrs.get("id"),
              ),
              help_text,
              errors,
              **hg.merge_html_attrs(attributes, {"_class": "bx--radio-button-wrapper"}),
          )
  
  
  class RadioSelect(BaseWidget):
      django_widget = widgets.RadioSelect
      carbon_input_class = "bx--radio-button"
      input_type = "radio"
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              hg.FIELDSET(
                  label,
                  hg.DIV(
                      hg.Iterator(
                          boundfield.subwidgets,
                          "radiobutton",
                          RadioButton(
                              label=Label(hg.C("radiobutton").data["label"]),
                              inputelement_attrs=_combine_lazy_dict(
                                  _combine_lazy_dict(
                                      inputelement_attrs,
                                      {
                                          "name": hg.C("radiobutton").data["name"],
                                          "value": hg.C("radiobutton").data["value"],
                                          "checked": hg.C("radiobutton").data["selected"],
                                      },
                                  ),
                                  hg.C("radiobutton").data["attrs"],
                              ),
                          ),
                      ),
                      _class="bx--radio-button-group  bx--radio-button-group--vertical",
                  ),
                  data_invalid=hg.If(getattr(errors, "condition", False), True),
              ),
              help_text,
              errors,
              **attributes,
          )
  
  
  class DatePicker(BaseWidget):
      django_widget = widgets.DateInput
      carbon_input_class = "bx--date-picker__input"
      input_type = "text"  # prevent browser style date picker but use carbon design
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          style_short=False,
          style_simple=False,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          super().__init__(
              hg.DIV(
                  label,
                  hg.If(
                      style_simple,
                      self.get_input_element(
                          inputelement_attrs,
                          errors,
                          data_invalid=hg.If(getattr(errors, "condition"), True),
                          pattern=hg.F(
                              lambda c: (
                                  TimeRE()
                                  .compile(
                                      hg.resolve_lazy(boundfield, c).field.widget.format
                                      or formats.get_format(
                                          hg.resolve_lazy(
                                              boundfield, c
                                          ).field.widget.format_key
                                      )[0]
                                  )
                                  .pattern
                              )
                          ),
                      ),
                      hg.DIV(
                          self.get_input_element(
                              inputelement_attrs,
                              errors,
                              data_date_picker_input=True,
                              data_invalid=hg.If(getattr(errors, "condition"), True),
                              data_date_format=hg.F(
                                  lambda c: to_php_formatstr(
                                      hg.resolve_lazy(boundfield, c).field.widget.format,
                                      hg.resolve_lazy(
                                          boundfield, c
                                      ).field.widget.format_key,
                                  )
                              ),
                          ),
                          Icon(
                              "calendar",
                              size=16,
                              _class="bx--date-picker__icon",
                              data_date_picker_icon="true",
                          ),
                          _class="bx--date-picker-input__wrapper",
                      ),
                  ),
                  help_text,
                  errors,
                  _class="bx--date-picker-container",
              ),
              **hg.merge_html_attrs(
                  attributes,
                  {
                      "data_date_picker": not style_simple,
                      "data_date_picker_type": None if style_simple else "single",
                      "_class": hg.BaseElement(
                          "bx--date-picker",
                          hg.If(
                              style_simple,
                              " bx--date-picker--simple",
                              " bx--date-picker--single",
                          ),
                          hg.If(style_short, " bx--date-picker--short"),
                      ),
                  },
              ),
          )
  
  
  class FileInput(BaseWidget):
      django_widget = widgets.FileInput
      carbon_input_class = "bx--file-input bx--visually-hidden"
      input_type = "file"
      clearable = False
  
      def __init__(
          self,
          label=None,
          help_text=None,
          errors=None,
          inputelement_attrs=None,
          boundfield=None,
          **attributes,
      ):
          inputelement_attrs = inputelement_attrs or {}
          uploadbutton = hg.LABEL(
              hg.SPAN(_("Select file"), role="button"),
              tabindex=0,
              _class=hg.BaseElement(
                  "bx--btn bx--btn--primary",
                  hg.If(inputelement_attrs.get("disabled"), " bx--btn--disabled"),
              ),
              data_file_drop_container=True,
              disabled=inputelement_attrs.get("disabled"),
              data_invalid=hg.If(getattr(errors, "condition", False), True),
              _for=inputelement_attrs.get("id"),
          )
          input = self.get_input_element(
              inputelement_attrs,
              errors,
              onload="""
  document.addEventListener('change', (e) => {
      this.parentElement.querySelector('[data-file-container]').innerHTML = '';
      var widget = new CarbonComponents.FileUploader(this.parentElement);
      widget._displayFilenames();
      widget.setState('edit');
  });
  """,
          )
          # we can only clear the field if it originates form a django field
          # otherwise it has no use
          clearbox = None
          if boundfield:
              checkbox_name = hg.F(
                  lambda c: hg.resolve_lazy(
                      boundfield, c
                  ).field.widget.clear_checkbox_name(
                      hg.resolve_lazy(boundfield, c).html_name
                  )
              )
              checkbox_id = hg.F(
                  lambda c: hg.resolve_lazy(boundfield, c).field.widget.clear_checkbox_id(
                      hg.resolve_lazy(checkbox_name, c)
                  )
              )
              clearbox = hg.If(
                  self.clearable,
                  hg.INPUT(
                      type="checkbox",
                      name=checkbox_name,
                      id=checkbox_id,
                      style="display: none",
                  ),
              )
  
          # clearbutton is always used, to allow clearing a just selected field in the browser
          clearbutton = hg.If(
              self.clearable,
              hg.SPAN(
                  hg.BUTTON(
                      Icon("close", size=16),
                      _class="bx--file-close",
                      type="button",
                      aria_label="close",
                      onclick=hg.If(
                          clearbox,
                          hg.format("$('#{}').checked = 'checked';", checkbox_id),
                      ),
                  ),
                  data_for=inputelement_attrs.get("id"),
                  _class="bx--file__state-container",
              ),
          )
  
          super().__init__(
              label,
              hg.DIV(
                  uploadbutton,
                  input,
                  clearbox,
                  hg.DIV(
                      hg.If(
                          inputelement_attrs.get("value"),
                          hg.SPAN(
                              hg.P(
                                  hg.If(
                                      hg.F(
                                          lambda c: hasattr(
                                              hg.resolve_lazy(inputelement_attrs, c)
                                              .get("value")
                                              .file,
                                              "name",
                                          )
                                      ),
                                      hg.A(
                                          hg.F(
                                              lambda c: os.path.basename(
                                                  hg.resolve_lazy(inputelement_attrs, c)
                                                  .get("value")
                                                  .name
                                              )
                                          ),
                                          href=hg.F(
                                              lambda c: settings.MEDIA_URL
                                              + hg.resolve_lazy(inputelement_attrs, c)
                                              .get("value")
                                              .name
                                          ),
                                      ),
                                      hg.F(
                                          lambda c: os.path.basename(
                                              hg.resolve_lazy(inputelement_attrs, c)
                                              .get("value")
                                              .name
                                          )
                                      ),
                                  ),
                                  _class="bx--file-filename",
                              ),
                              clearbutton,
                              _class="bx--file__selected-file",
                          ),
                      ),
                      data_file_container=True,
                      _class="bx--file-container",
                  ),
                  help_text,
                  errors,
                  _class="bx--file",
                  data_file=True,
              ),
              **attributes,
          )
  
  
  class ClearableFileInput(FileInput):
      django_widget = widgets.ClearableFileInput
      clearable = True
  
  
  class LazySelect(Select):
      django_widget = django_countries.widgets.LazySelect
  
  
  def _append_classes(lazy_attrs, *_classes):
      def wrapper_func(context):
          _classlist = []
          for _class in _classes:
              _classlist.append(_class)
              _classlist.append(" ")
          ret = hg.resolve_lazy(lazy_attrs, context) or {}
          ret["_class"] = hg.BaseElement(ret.get("_class", ""), " ", *_classlist)
          return ret
  
      return hg.F(wrapper_func)
  
  
  def _combine_lazy_dict(attrs1, attrs2):
      return hg.F(
          lambda c: {
              **(hg.resolve_lazy(attrs1, c) or {}),
              **(hg.resolve_lazy(attrs2, c) or {}),
          }
      )
  
  
  def _gen_optgroup(boundfield):
      def wrapper(context):
          bfield = hg.resolve_lazy(boundfield, context)
          return bfield.field.widget.optgroups(
              bfield.name,
              bfield.field.widget.format_value(bfield.value()),
          )
  
      return hg.F(wrapper)
  
  
  # based on https://github.com/django/django/blob/c6c6cd3c5ad9c36795bb120e521590424f034ae4/django/forms/widgets.py#L587
  def _optgroups_from_choices(optchoices, name, value):
      groups = []
  
      for index, (option_value, option_label) in enumerate(optchoices):
          if option_value is None:
              option_value = ""
  
          subgroup = []
          if isinstance(option_label, (list, tuple)):
              group_name = option_value
              subindex = 0
              choices = option_label
          else:
              group_name = None
              subindex = None
              choices = [(option_value, option_label)]
          groups.append((group_name, subgroup, index))
  
          for subvalue, sublabel in choices:
              selected = hg.F(
                  lambda c, v=subvalue: hg.resolve_lazy(v, c) == hg.resolve_lazy(value, c)
              )
              subgroup.append(
                  {
                      "name": name,
                      "value": subvalue,
                      "label": sublabel,
                      "selected": selected,
                      "attrs": {
                          "selected": selected,
                      },
                  }
              )
              if subindex is not None:
                  subindex += 1
      return groups
  