function bind(view, el, binding) {
    if (!el) return;
    const param = binding.param;
    let bind = binding.state;
    if (!bind) {
      bind = binding.state = {
        elements: null,
        active: false,
        set: null,
        update: value => {
          if (value != view.signal(param.signal)) {
            view.runAsync(null, () => {
              bind.source = true;
              view.signal(param.signal, value);
            });
          }
        }
      };
      if (param.debounce) {
        bind.update = debounce(param.debounce, bind.update);
      }
    }
    const create = param.input == null && param.element ? target : generate;
    create(bind, el, param, view);
    if (!bind.active) {
      view.on(view._signals[param.signal], null, () => {
        bind.source ? bind.source = false : bind.set(view.signal(param.signal));
      });
      bind.active = true;
    }
    return bind;
  }
Bind a signal to an external HTML input element. The resulting two-way
binding will propagate input changes to signals, and propagate signal
changes to the input element state. If this view instance has no parent
element, we assume the view is headless and no bindings are created.
@param {Element|string} el - The parent DOM element to which the input
  element should be appended as a child. If string-valued, this argument
  will be treated as a CSS selector. If null or undefined, the parent
  element of this view will be used as the element.
@param {object} param - The binding parameters which specify the signal
  to bind to, the input element type, and type-specific configuration.
@return {View} - This view instance.