docs: function (input, options, plugin_count) {
          this.VERSION = "2.3.0";
          this.input = input;
          this.plugin_count = plugin_count;
          this.current_plugin = 0;
          this.calc_count = 0;
          this.update_tm = 0;
          this.old_from = 0;
          this.old_to = 0;
          this.old_min_interval = null;
          this.raf_id = null;
          this.dragging = false;
          this.force_redraw = false;
          this.no_diapason = false;
          this.has_tab_index = true;
          this.is_key = false;
          this.is_update = false;
          this.is_start = true;
          this.is_finish = false;
          this.is_active = false;
          this.is_resize = false;
          this.is_click = false;
  
          options = options || {};
  
          // cache for links to all DOM elements
          this.$cache = {
              win: $(window),
              body: $(document.body),
              input: $(input),
              cont: null,
              rs: null,
              min: null,
              max: null,
              from: null,
              to: null,
              single: null,
              bar: null,
              line: null,
              s_single: null,
              s_from: null,
              s_to: null,
              shad_single: null,
              shad_from: null,
              shad_to: null,
              edge: null,
              grid: null,
              grid_labels: []
          };
  
          // storage for measure variables
          this.coords = {
              // left
              x_gap: 0,
              x_pointer: 0,
  
              // width
              w_rs: 0,
              w_rs_old: 0,
              w_handle: 0,
  
              // percents
              p_gap: 0,
              p_gap_left: 0,
              p_gap_right: 0,
              p_step: 0,
              p_pointer: 0,
              p_handle: 0,
              p_single_fake: 0,
              p_single_real: 0,
              p_from_fake: 0,
              p_from_real: 0,
              p_to_fake: 0,
              p_to_real: 0,
              p_bar_x: 0,
              p_bar_w: 0,
  
              // grid
              grid_gap: 0,
              big_num: 0,
              big: [],
              big_w: [],
              big_p: [],
              big_x: []
          };
  
          // storage for labels measure variables
          this.labels = {
              // width
              w_min: 0,
              w_max: 0,
              w_from: 0,
              w_to: 0,
              w_single: 0,
  
              // percents
              p_min: 0,
              p_max: 0,
              p_from_fake: 0,
              p_from_left: 0,
              p_to_fake: 0,
              p_to_left: 0,
              p_single_fake: 0,
              p_single_left: 0
          };
  
  
  
          /**
           * get and validate config
           */
          var $inp = this.$cache.input,
              val = $inp.prop("value"),
              config, config_from_data, prop;
  
          // default config
          config = {
              skin: "flat",
              type: "single",
  
              min: 10,
              max: 100,
              from: null,
              to: null,
              step: 1,
  
              min_interval: 0,
              max_interval: 0,
              drag_interval: false,
  
              values: [],
              p_values: [],
  
              from_fixed: false,
              from_min: null,
              from_max: null,
              from_shadow: false,
  
              to_fixed: false,
              to_min: null,
              to_max: null,
              to_shadow: false,
  
              prettify_enabled: true,
              prettify_separator: " ",
              prettify: null,
  
              force_edges: false,
  
              keyboard: true,
  
              grid: false,
              grid_margin: true,
              grid_num: 4,
              grid_snap: false,
  
              hide_min_max: false,
              hide_from_to: false,
  
              prefix: "",
              postfix: "",
              max_postfix: "",
              decorate_both: true,
              values_separator: " — ",
  
              input_values_separator: ";",
  
              disable: false,
              block: false,
  
              extra_classes: "",
  
              scope: null,
              onStart: null,
              onChange: null,
              onFinish: null,
              onUpdate: null
          };
  
  
          // check if base element is input
          if ($inp[0].nodeName !== "INPUT") {
              console && console.warn && console.warn("Base element should be <input>!", $inp[0]);
          }
  
  
          // config from data-attributes extends js config
          config_from_data = {
              skin: $inp.data("skin"),
              type: $inp.data("type"),
  
              min: $inp.data("min"),
              max: $inp.data("max"),
              from: $inp.data("from"),
              to: $inp.data("to"),
              step: $inp.data("step"),
  
              min_interval: $inp.data("minInterval"),
              max_interval: $inp.data("maxInterval"),
              drag_interval: $inp.data("dragInterval"),
  
              values: $inp.data("values"),
  
              from_fixed: $inp.data("fromFixed"),
              from_min: $inp.data("fromMin"),
              from_max: $inp.data("fromMax"),
              from_shadow: $inp.data("fromShadow"),
  
              to_fixed: $inp.data("toFixed"),
              to_min: $inp.data("toMin"),
              to_max: $inp.data("toMax"),
              to_shadow: $inp.data("toShadow"),
  
              prettify_enabled: $inp.data("prettifyEnabled"),
              prettify_separator: $inp.data("prettifySeparator"),
  
              force_edges: $inp.data("forceEdges"),
  
              keyboard: $inp.data("keyboard"),
  
              grid: $inp.data("grid"),
              grid_margin: $inp.data("gridMargin"),
              grid_num: $inp.data("gridNum"),
              grid_snap: $inp.data("gridSnap"),
  
              hide_min_max: $inp.data("hideMinMax"),
              hide_from_to: $inp.data("hideFromTo"),
  
              prefix: $inp.data("prefix"),
              postfix: $inp.data("postfix"),
              max_postfix: $inp.data("maxPostfix"),
              decorate_both: $inp.data("decorateBoth"),
              values_separator: $inp.data("valuesSeparator"),
  
              input_values_separator: $inp.data("inputValuesSeparator"),
  
              disable: $inp.data("disable"),
              block: $inp.data("block"),
  
              extra_classes: $inp.data("extraClasses"),
          };
          config_from_data.values = config_from_data.values && config_from_data.values.split(",");
  
          for (prop in config_from_data) {
              if (config_from_data.hasOwnProperty(prop)) {
                  if (config_from_data[prop] === undefined || config_from_data[prop] === "") {
                      delete config_from_data[prop];
                  }
              }
          }
  
  
          // input value extends default config
          if (val !== undefined && val !== "") {
              val = val.split(config_from_data.input_values_separator || options.input_values_separator || ";");
  
              if (val[0] && val[0] == +val[0]) {
                  val[0] = +val[0];
              }
              if (val[1] && val[1] == +val[1]) {
                  val[1] = +val[1];
              }
  
              if (options && options.values && options.values.length) {
                  config.from = val[0] && options.values.indexOf(val[0]);
                  config.to = val[1] && options.values.indexOf(val[1]);
              } else {
                  config.from = val[0] && +val[0];
                  config.to = val[1] && +val[1];
              }
          }
  
  
  
          // js config extends default config
          $.extend(config, options);
  
  
          // data config extends config
          $.extend(config, config_from_data);
          this.options = config;
  
  
  
          // validate config, to be sure that all data types are correct
          this.update_check = {};
          this.validate();
  
  
  
          // default result object, returned to callbacks
          this.result = {
              input: this.$cache.input,
              slider: null,
  
              min: this.options.min,
              max: this.options.max,
  
              from: this.options.from,
              from_percent: 0,
              from_value: null,
  
              to: this.options.to,
              to_percent: 0,
              to_value: null
          };
  
  
  
          this.init();
      }