[
  {
    "path": ".eslintrc.json",
    "content": "{\n    \"extends\": \"standard\",\n    \"rules\": {\n        \"semi\": 0,\n        \"no-undef\": 0,\n        \"operator-linebreak\": 0,\n        \"space-before-function-paren\": 0,\n        \"indent\": [\"error\", 2],\n    \"prefer-regex-literals\": 0,\n    \"quote-props\": 0,\n    \"prefer-const\": 0,\n    \"dot-notation\": 0\n    }\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create bug report\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Example**\nProvide link to example, use [jsfiddle](https://jsfiddle.net/Stryzhevskyi/rpsa16fn/) as a template.\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Click on '....'\n2. Move handle '....'\n3. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/workflows/publish-from-tag.yaml",
    "content": "name: Publish Package\n\non:\n  push:\n    tags:\n      - '*'\n\npermissions:\n  id-token: write  # Required for OIDC\n  contents: read\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - uses: actions/setup-node@v6\n        with:\n          node-version: '24'\n          registry-url: 'https://registry.npmjs.org'\n      - run: npm ci\n      - run: npm run build\n      - run: npm publish"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.idea/\n.directory\n.history/\n.vscode/\ndist/"
  },
  {
    "path": ".jshintrc",
    "content": "{\n  \"node\": true,\n  \"browser\": true,\n  \"esnext\": true,\n  \"bitwise\": true,\n  \"camelcase\": true,\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"indent\": 2,\n  \"latedef\": true,\n  \"newcap\": true,\n  \"noarg\": true,\n  \"quotmark\": \"single\",\n  \"regexp\": true,\n  \"undef\": true,\n  \"unused\": true,\n  \"strict\": true,\n  \"trailing\": true,\n  \"smarttabs\": true,\n  \"globals\": {\n    \"jQuery\": true,\n    \"define\": true\n  }\n}\n"
  },
  {
    "path": ".npmignore",
    "content": ".eslintrc.json\n.git\n.github\n.gitignore\n.history\n.jshintrc\n.npmignore\nbower.json\nexample\nnode_modules\npostcss.config.js\nsrc\nvite.config.js"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Serhii\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# rangeSlider\n\n> Simple, small and fast vanilla JavaScript polyfill for the HTML5 `<input type=\"range\">` slider element.\n> Forked from [André Ruffert's jQuery plugin](https://github.com/andreruffert/rangeslider.js)\n\nCheck out the [examples](http://stryzhevskyi.github.io/rangeSlider/).\n\n* Touchscreen friendly\n* Recalculates `onresize`\n* Small and fast\n* Supports all major browsers\n* Buffer progressbar (for downloading progress etc.)\n\n## Install\n\nInstall with [npm](https://www.npmjs.com/package/rangeslider-pure):\n\n```\nnpm install --save rangeslider-pure\n```\n\n## Usage\n\n```js\n// Initialize a new plugin instance for one element or NodeList of elements.\nconst slider = document.querySelector('input[type=\"range\"]');\nrangeSlider.create(slider, {\n    polyfill: true,     // Boolean, if true, custom markup will be created\n    root: document,\n    rangeClass: 'rangeSlider',\n    disabledClass: 'rangeSlider--disabled',\n    fillClass: 'rangeSlider__fill',\n    bufferClass: 'rangeSlider__buffer',\n    handleClass: 'rangeSlider__handle',\n    startEvent: ['mousedown', 'touchstart', 'pointerdown'],\n    moveEvent: ['mousemove', 'touchmove', 'pointermove'],\n    endEvent: ['mouseup', 'touchend', 'pointerup'],\n    vertical: false,    // Boolean, if true slider will be displayed in vertical orientation\n    min: null,          // Number, 0\n    max: null,          // Number, 100\n    step: null,         // Number, 1\n    value: null,        // Number, center of slider\n    buffer: null,       // Number, in percent, 0 by default\n    stick: null,        // [Number stickTo, Number stickRadius] : use it if handle should stick to ${stickTo}-th value in ${stickRadius}\n    borderRadius: 10,   // Number, if you're using buffer + border-radius in css\n    onInit: function () {\n        console.info('onInit')\n    },\n    onSlideStart: function (value, percent, position) {\n        console.info('onSlideStart', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n    },\n    onSlide: function (value, percent, position) {\n        console.log('onSlide', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n    },\n    onSlideEnd: function (value, percent, position) {\n        console.warn('onSlideEnd', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n    }\n});\n\n// update position\nconst triggerEvents = true; // or false\nslider.rangeSlider.update({\n    min: 0,\n    max: 20,\n    step: 0.5,\n    value: 1.5,\n    buffer: 70\n}, triggerEvents);\n\n```\n\n```html\n<input\n    type=\"range\"\n    min=\"0\"\n    max=\"100\"\n    step=\"1\"\n    data-buffer=\"60\" />\n```\n\n### Internal APIs:\n```js\n/*\n * @see src/utils/dom.js\n */\nRangeSlider.dom;\n/*\n * @see src/utils/functions.js\n */\nRangeSlider.functions;\nRangeSlider.version;\n\n```\n\nUse the [JSFiddle](https://jsfiddle.net/Stryzhevskyi/rpsa16fn/) template for issues.\n\nAlternative template on [StackBlitz](https://stackblitz.com/edit/rangeslider-pure-example).\n\n## License\nMIT\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"rangeslider-pure\",\n  \"version\": \"0.5.0\",\n  \"homepage\": \"https://github.com/Stryzhevskyi/rangeSlider\",\n  \"authors\": [\n    \"Stryzhevskyi (https://github.com/Stryzhevskyi)\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Stryzhevskyi/rangeSlider.git\"\n  },\n  \"description\": \"Simple, small and fast vanilla JavaScript polyfill for the HTML5 <input type=\\\"range\\\"> slider element\",\n  \"main\": [\n    \"dist/range-slider.js\",\n    \"dist/range-slider.css\"\n  ],\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"input\",\n    \"range\",\n    \"slider\",\n    \"rangeSlider\",\n    \"rangeSlider.js\",\n    \"polyfill\",\n    \"vanilla\",\n    \"pure\"\n  ],\n  \"ignore\": [\n    \"**/.*\",\n    \"*.json\",\n    \"src\",\n    \"example\",\n    \"node_modules\",\n    \"bower_components\",\n    \"gulpfile.js\"\n  ],\n  \"dependencies\": {}\n}\n"
  },
  {
    "path": "example/index-esm.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <title>range-slider.js</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <!-- range-slider.css is injected via JS module in dev; link dist/range-slider.css when using the built bundle -->\n  <!--<link rel=\"stylesheet\" href=\"../dist/range-slider.css\">-->\n  <!--<link rel=\"stylesheet\" href=\"range-slider-flat.css\">-->\n  <style>\n    *,\n    *:before,\n    *:after {\n      -webkit-box-sizing: border-box;\n      -moz-box-sizing: border-box;\n      box-sizing: border-box;\n    }\n\n    html {\n      color: #404040;\n      font-family: Helvetica, arial, sans-serif;\n    }\n\n    body {\n      padding: 50px 20px;\n      margin: 0 auto;\n      max-width: 800px;\n    }\n\n    output {\n      display: block;\n      font-size: 30px;\n      font-weight: bold;\n      text-align: center;\n      margin: 30px 0;\n      width: 100%;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <h2>Comparison to native element</h2>\n    <input type=\"range\" min=\"0\" max=\"5\" data-rangeSlider title=\"Slide me!\">\n    <br>\n    <br>\n    <input type=\"range\" min=\"0\" max=\"5\" style=\"width:100%;\" title=\"Slide me!\">\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Negative attributes</h2>\n    <input type=\"range\" min=\"-20\" max=\"20\" data-rangeSlider title=\"\">\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Vertical mode</h2>\n    <div style=\"height: 200px;\">\n      <input type=\"range\" id=\"vertical\">\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Floating point boundaries</h2>\n\n    <div>\n      <input type=\"range\" min=\"10\" max=\"11\" step=\"0.1\" value=\"10.2\" data-rangeSlider>\n      <output></output>\n    </div>\n    <div>\n      <input type=\"range\" min=\"0.1\" max=\"3\" step=\"0.1\" value=\"0.5\" data-rangeSlider>\n      <output></output>\n    </div>\n    <div>\n      <input type=\"range\" min=\"0.111\" max=\"3.33\" step=\"0.111\" value=\"1.776\" data-rangeSlider>\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Stick example</h2>\n    <h4>Handle will stick to Nth number in X radius, 10 and 0.7 in example</h4>\n    <div>\n      <input type=\"range\" min=\"0\" max=\"100\" step=\"0.1\" value=\"0\" stick=\"10 0.7\" data-rangeSlider>\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2><code>value=\"0\"</code></h2>\n    <input type=\"range\" value=\"0\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-disabled\">\n    <h2><code>disabled</code></h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider disabled>\n    <output></output>\n    <button data-behaviour=\"toggle\">Toggle disabled state</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2><code>max=\"0\"</code> disables slider</h2>\n    <input type=\"range\" max=\"0\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-change-value\">\n    <h2>Programmatic value changes</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider>\n    <output></output>\n    <input type=\"number\" value=\"10\">\n    <button>Change value</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-buffer\">\n    <h2>Predefined buffer position data-buffer=\"60\"</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-buffer-set\">\n    <h2>Update buffer position</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n    <input type=\"number\" value=\"80\"> %\n    <button>Change value</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-update-range\">\n    <h2>Update range</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" step=\"10\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n    <button>Update range {min : 0, max : 20, step : 0.5, value : 1.5, buffer : 70}</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-destroy\">\n    <h2>Destroy a plugin instance</h2>\n    <input type=\"range\" min=\"10\" max=\"1000\" step=\"10\" value=\"500\" data-rangeSlider>\n    <output></output>\n    <button data-behaviour=\"destroy\">Destroy</button>\n    <button data-behaviour=\"initialize\">Initialize</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-hidden\">\n    <h2>Consider initialization and update of hidden elements</h2>\n\n    <div style=\"display:none\">\n      <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider>\n      <output></output>\n    </div>\n    <button data-behaviour=\"toggle\">Toggle visibility</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-hidden-native\">\n    <h2>Combination with native <code>&lt;details&gt;</code> element</h2>\n    <details>\n      <summary>Toggle</summary>\n      <br>\n      <br>\n      <input type=\"range\" min=\"10\" max=\"100\" value=\"20\" data-rangeSlider>\n      <output></output>\n    </details>\n  </div>\n\n  <script type=\"module\">\n    import rangeSlider from '/src/range-slider.js';\n    (function () {\n\n      var selector = '[data-rangeSlider]',\n        elements = document.querySelectorAll(selector);\n\n      // Example functionality to demonstrate a value feedback\n      function valueOutput(element) {\n        var value = element.value,\n          output = element.parentNode.getElementsByTagName('output')[0];\n        output.innerHTML = value;\n      }\n\n      for (var i = elements.length - 1; i >= 0; i--) {\n        valueOutput(elements[i]);\n      }\n\n      Array.prototype.slice.call(document.querySelectorAll('input[type=\"range\"]')).forEach(function (el) {\n        el.addEventListener('input', function (e) {\n          valueOutput(e.target);\n        }, false);\n      });\n\n\n      // Example functionality to demonstrate disabled functionality\n      var toggleBtnDisable = document.querySelector('#js-example-disabled button[data-behaviour=\"toggle\"]');\n      toggleBtnDisable.addEventListener('click', function (e) {\n        var inputRange = toggleBtnDisable.parentNode.querySelector('input[type=\"range\"]');\n        console.log(inputRange);\n        if (inputRange.disabled) {\n          inputRange.disabled = false;\n        }\n        else {\n          inputRange.disabled = true;\n        }\n        inputRange.rangeSlider.update();\n      }, false);\n\n      // Example functionality to demonstrate programmatic value changes\n      var changeValBtn = document.querySelector('#js-example-change-value button');\n      changeValBtn.addEventListener('click', function (e) {\n        var inputRange = changeValBtn.parentNode.querySelector('input[type=\"range\"]'),\n          value = changeValBtn.parentNode.querySelector('input[type=\"number\"]').value,\n          event = document.createEvent('Event');\n\n        event.initEvent('change', true, true);\n\n        inputRange.value = value;\n        inputRange.dispatchEvent(event);\n      }, false);\n\n      // Example functionality to demonstrate programmatic buffer set\n      var stBufferBtn = document.querySelector('#js-example-buffer-set button');\n      stBufferBtn.addEventListener('click', function (e) {\n        var inputRange = stBufferBtn.parentNode.querySelector('input[type=\"range\"]'),\n          value = stBufferBtn.parentNode.querySelector('input[type=\"number\"]').value;\n\n        inputRange.rangeSlider.update({ buffer: value });\n      }, false);\n\n      // Example functionality to demonstrate destroy functionality\n      var destroyBtn = document.querySelector('#js-example-destroy button[data-behaviour=\"destroy\"]');\n      destroyBtn.addEventListener('click', function (e) {\n        var inputRange = destroyBtn.parentNode.querySelector('input[type=\"range\"]');\n        console.log(inputRange);\n        inputRange.rangeSlider.destroy();\n      }, false);\n\n      var initBtn = document.querySelector('#js-example-destroy button[data-behaviour=\"initialize\"]');\n\n      initBtn.addEventListener('click', function (e) {\n        var inputRange = initBtn.parentNode.querySelector('input[type=\"range\"]');\n        rangeSlider.create(inputRange, {});\n      }, false);\n\n      //update range\n      var updateBtn1 = document.querySelector('#js-example-update-range button');\n      updateBtn1.addEventListener('click', function (e) {\n        var inputRange = updateBtn1.parentNode.querySelector('input[type=\"range\"]');\n        inputRange.rangeSlider.update({ min: 0, max: 20, step: 0.5, value: 1.5, buffer: 70 });\n      }, false);\n\n\n      var toggleBtn = document.querySelector('#js-example-hidden button[data-behaviour=\"toggle\"]');\n      toggleBtn.addEventListener('click', function (e) {\n        var container = e.target.previousElementSibling;\n        if (container.style.cssText.match(/display[\\s:]{1,3}none/)) {\n          container.style.cssText = '';\n        } else {\n          container.style.cssText = 'display: none;';\n        }\n      }, false);\n\n      // Basic rangeSlider initialization\n      rangeSlider.create(elements, {\n\n        // Callback function\n        onInit: function () {\n        },\n\n        // Callback function\n        onSlideStart: function (value, percent, position) {\n          console.info('onSlideStart', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        },\n\n        // Callback function\n        onSlide: function (value, percent, position) {\n          console.log('onSlide', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        },\n\n        // Callback function\n        onSlideEnd: function (value, percent, position) {\n          console.warn('onSlideEnd', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        }\n      });\n\n      rangeSlider.create(document.querySelector('#vertical'), {\n        vertical: true\n      });\n\n    })();\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "example/index-umd.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf-8\">\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n  <title>range-slider.js</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <!-- range-slider.css is injected via JS module in dev; link dist/range-slider.css when using the built bundle -->\n  <link rel=\"stylesheet\" href=\"/dist/range-slider.css\">\n  <!--<link rel=\"stylesheet\" href=\"range-slider-flat.css\">-->\n  <style>\n    *,\n    *:before,\n    *:after {\n      -webkit-box-sizing: border-box;\n      -moz-box-sizing: border-box;\n      box-sizing: border-box;\n    }\n\n    html {\n      color: #404040;\n      font-family: Helvetica, arial, sans-serif;\n    }\n\n    body {\n      padding: 50px 20px;\n      margin: 0 auto;\n      max-width: 800px;\n    }\n\n    output {\n      display: block;\n      font-size: 30px;\n      font-weight: bold;\n      text-align: center;\n      margin: 30px 0;\n      width: 100%;\n    }\n  </style>\n</head>\n\n<body>\n  <div>\n    <h2>Comparison to native element</h2>\n    <input type=\"range\" min=\"0\" max=\"5\" data-rangeSlider title=\"Slide me!\">\n    <br>\n    <br>\n    <input type=\"range\" min=\"0\" max=\"5\" style=\"width:100%;\" title=\"Slide me!\">\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Negative attributes</h2>\n    <input type=\"range\" min=\"-20\" max=\"20\" data-rangeSlider title=\"\">\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Vertical mode</h2>\n    <div style=\"height: 200px;\">\n      <input type=\"range\" id=\"vertical\">\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Floating point boundaries</h2>\n\n    <div>\n      <input type=\"range\" min=\"10\" max=\"11\" step=\"0.1\" value=\"10.2\" data-rangeSlider>\n      <output></output>\n    </div>\n    <div>\n      <input type=\"range\" min=\"0.1\" max=\"3\" step=\"0.1\" value=\"0.5\" data-rangeSlider>\n      <output></output>\n    </div>\n    <div>\n      <input type=\"range\" min=\"0.111\" max=\"3.33\" step=\"0.111\" value=\"1.776\" data-rangeSlider>\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2>Stick example</h2>\n    <h4>Handle will stick to Nth number in X radius, 10 and 0.15 in example</h4>\n    <div>\n      <input type=\"range\" min=\"0\" max=\"100\" step=\"0.1\" value=\"0\" stick=\"10 0.1\" data-rangeSlider>\n      <output></output>\n    </div>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2><code>value=\"0\"</code></h2>\n    <input type=\"range\" value=\"0\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-disabled\">\n    <h2><code>disabled</code></h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider disabled>\n    <output></output>\n    <button data-behaviour=\"toggle\">Toggle disabled state</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div>\n    <h2><code>max=\"0\"</code> disables slider</h2>\n    <input type=\"range\" max=\"0\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-change-value\">\n    <h2>Programmatic value changes</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider>\n    <output></output>\n    <input type=\"number\" value=\"10\">\n    <button>Change value</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-buffer\">\n    <h2>Predefined buffer position data-buffer=\"60\"</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-buffer-set\">\n    <h2>Update buffer position</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n    <input type=\"number\" value=\"80\"> %\n    <button>Change value</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-update-range\">\n    <h2>Update range</h2>\n    <input type=\"range\" min=\"10\" max=\"100\" step=\"10\" data-buffer=\"60\" data-rangeSlider>\n    <output></output>\n    <button>Update range {min : 0, max : 20, step : 0.5, value : 1.5, buffer : 70}</button>\n  </div>\n\n  <br>\n  <br>\n  <br>\n  <br>\n\n  <div id=\"js-example-destroy\">\n    <h2>Destroy a plugin instance</h2>\n    <input type=\"range\" min=\"10\" max=\"1000\" step=\"10\" value=\"500\" data-rangeSlider>\n    <output></output>\n    <button data-behaviour=\"destroy\">Destroy</button>\n    <button data-behaviour=\"initialize\">Initialize</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-hidden\">\n    <h2>Consider initialization and update of hidden elements</h2>\n\n    <div style=\"display:none\">\n      <input type=\"range\" min=\"10\" max=\"100\" data-rangeSlider>\n      <output></output>\n    </div>\n    <button data-behaviour=\"toggle\">Toggle visibility</button>\n  </div>\n\n  <br>\n  <br>\n\n  <div id=\"js-example-hidden-native\">\n    <h2>Combination with native <code>&lt;details&gt;</code> element</h2>\n    <details>\n      <summary>Toggle</summary>\n      <br>\n      <br>\n      <input type=\"range\" min=\"10\" max=\"100\" value=\"20\" data-rangeSlider>\n      <output></output>\n    </details>\n  </div>\n\n  <script src=\"/dist/range-slider.js\"></script>\n  <script>\n    var rangeSlider = window.rangeSlider;\n    console.log('rangeSlider', rangeSlider);\n    (function () {\n\n      var selector = '[data-rangeSlider]',\n        elements = document.querySelectorAll(selector);\n\n      // Example functionality to demonstrate a value feedback\n      function valueOutput(element) {\n        var value = element.value,\n          output = element.parentNode.getElementsByTagName('output')[0];\n        output.innerHTML = value;\n      }\n\n      for (var i = elements.length - 1; i >= 0; i--) {\n        valueOutput(elements[i]);\n      }\n\n      Array.prototype.slice.call(document.querySelectorAll('input[type=\"range\"]')).forEach(function (el) {\n        el.addEventListener('input', function (e) {\n          valueOutput(e.target);\n        }, false);\n      });\n\n\n      // Example functionality to demonstrate disabled functionality\n      var toggleBtnDisable = document.querySelector('#js-example-disabled button[data-behaviour=\"toggle\"]');\n      toggleBtnDisable.addEventListener('click', function (e) {\n        var inputRange = toggleBtnDisable.parentNode.querySelector('input[type=\"range\"]');\n        console.log(inputRange);\n        if (inputRange.disabled) {\n          inputRange.disabled = false;\n        }\n        else {\n          inputRange.disabled = true;\n        }\n        inputRange.rangeSlider.update();\n      }, false);\n\n      // Example functionality to demonstrate programmatic value changes\n      var changeValBtn = document.querySelector('#js-example-change-value button');\n      changeValBtn.addEventListener('click', function (e) {\n        var inputRange = changeValBtn.parentNode.querySelector('input[type=\"range\"]'),\n          value = changeValBtn.parentNode.querySelector('input[type=\"number\"]').value,\n          event = document.createEvent('Event');\n\n        event.initEvent('change', true, true);\n\n        inputRange.value = value;\n        inputRange.dispatchEvent(event);\n      }, false);\n\n      // Example functionality to demonstrate programmatic buffer set\n      var stBufferBtn = document.querySelector('#js-example-buffer-set button');\n      stBufferBtn.addEventListener('click', function (e) {\n        var inputRange = stBufferBtn.parentNode.querySelector('input[type=\"range\"]'),\n          value = stBufferBtn.parentNode.querySelector('input[type=\"number\"]').value;\n\n        inputRange.rangeSlider.update({ buffer: value });\n      }, false);\n\n      // Example functionality to demonstrate destroy functionality\n      var destroyBtn = document.querySelector('#js-example-destroy button[data-behaviour=\"destroy\"]');\n      destroyBtn.addEventListener('click', function (e) {\n        var inputRange = destroyBtn.parentNode.querySelector('input[type=\"range\"]');\n        console.log(inputRange);\n        inputRange.rangeSlider.destroy();\n      }, false);\n\n      var initBtn = document.querySelector('#js-example-destroy button[data-behaviour=\"initialize\"]');\n\n      initBtn.addEventListener('click', function (e) {\n        var inputRange = initBtn.parentNode.querySelector('input[type=\"range\"]');\n        rangeSlider.create(inputRange, {});\n      }, false);\n\n      //update range\n      var updateBtn1 = document.querySelector('#js-example-update-range button');\n      updateBtn1.addEventListener('click', function (e) {\n        var inputRange = updateBtn1.parentNode.querySelector('input[type=\"range\"]');\n        inputRange.rangeSlider.update({ min: 0, max: 20, step: 0.5, value: 1.5, buffer: 70 });\n      }, false);\n\n\n      var toggleBtn = document.querySelector('#js-example-hidden button[data-behaviour=\"toggle\"]');\n      toggleBtn.addEventListener('click', function (e) {\n        var container = e.target.previousElementSibling;\n        if (container.style.cssText.match(/display[\\s:]{1,3}none/)) {\n          container.style.cssText = '';\n        } else {\n          container.style.cssText = 'display: none;';\n        }\n      }, false);\n\n      // Basic rangeSlider initialization\n      rangeSlider.create(elements, {\n\n        // Callback function\n        onInit: function () {\n        },\n\n        // Callback function\n        onSlideStart: function (value, percent, position) {\n          console.info('onSlideStart', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        },\n\n        // Callback function\n        onSlide: function (value, percent, position) {\n          console.log('onSlide', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        },\n\n        // Callback function\n        onSlideEnd: function (value, percent, position) {\n          console.warn('onSlideEnd', 'value: ' + value, 'percent: ' + percent, 'position: ' + position);\n        }\n      });\n\n      rangeSlider.create(document.querySelector('#vertical'), {\n        vertical: true\n      });\n\n    })();\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "example/range-slider-flat.css",
    "content": ".rangeSlider,\n.rangeSlider__fill {\n    background: #7f8c8d;\n    display: block;\n    height: 8px;\n    width: 100%;\n    -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);\n    -moz-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.3);\n    box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.5);\n    -webkit-border-radius: 10px;\n    -moz-border-radius: 10px;\n    -ms-border-radius: 10px;\n    -o-border-radius: 10px;\n    border-radius: 4px;\n}\n\n.rangeSlider {\n    position: relative;\n}\n\n.rangeSlider--disabled {\n    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);\n    opacity: 0.4;\n}\n\n.rangeSlider__fill {\n    background: #FFFFFF;\n    position: absolute;\n    top: 0;\n}\n\n.rangeSlider__handle {\n    background: white;\n    border: 1px solid #ccc;\n    cursor: pointer;\n    display: inline-block;\n    width: 22px;\n    height: 21px;\n    position: absolute;\n    top: -7px;\n    background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(100%, rgba(0, 0, 0, 0.1)));\n    background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));\n    background-image: -moz-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));\n    background-image: -o-linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));\n    background-image: linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));\n    -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);\n    -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);\n    box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);\n    -webkit-border-radius: 50%;\n    -moz-border-radius: 50%;\n    -ms-border-radius: 50%;\n    -o-border-radius: 50%;\n    border-radius: 50%;\n}\n\n.rangeSlider__handle:after {\n    content: \"\";\n    display: block;\n    width: 10px;\n    height: 10px;\n    margin: auto;\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.13)), color-stop(100%, rgba(255, 255, 255, 0)));\n    background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));\n    background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));\n    background-image: -o-linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));\n    background-image: linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));\n    -webkit-border-radius: 50%;\n    -moz-border-radius: 50%;\n    -ms-border-radius: 50%;\n    -o-border-radius: 50%;\n    border-radius: 50%;\n}\n\n.rangeSlider__handle:active {\n    background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, rgba(0, 0, 0, 0.1)), color-stop(100%, rgba(0, 0, 0, 0.12)));\n    background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));\n    background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));\n    background-image: -o-linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));\n    background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));\n    outline: none;\n}\n\ninput[type=\"range\"]:focus + .rangeSlider .rangeSlider__handle {\n    -webkit-box-shadow: 0 0 8px rgba(142, 68, 173, 0.9);\n    -moz-box-shadow: 0 0 8px rgba(142, 68, 173, 0.9);\n    box-shadow: 0 0 8px rgba(142, 68, 173, 0.9);\n}\n\n.rangeSlider__buffer {\n    position: absolute;\n    top: 2px;\n    height: 4px;\n    background: #2c3e50;\n    border-radius: 2px;\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"rangeslider-pure\",\n  \"title\": \"range-slider\",\n  \"description\": \"Simple, small and fast vanilla JavaScript polyfill for the HTML5 <input type=\\\"range\\\"> slider element\",\n  \"version\": \"0.5.0\",\n  \"type\": \"module\",\n  \"main\": \"dist/range-slider.js\",\n  \"module\": \"dist/range-slider.esm.js\",\n  \"types\": \"dist/range-slider.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/range-slider.esm.js\",\n      \"require\": \"./dist/range-slider.js\"\n    },\n    \"./dist/range-slider.css\": \"./dist/range-slider.css\"\n  },\n  \"files\": [\n    \"dist\",\n    \"LICENSE.md\",\n    \"README.md\"\n  ],\n  \"scripts\": {\n    \"dev\": \"vite serve\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"lint\": \"eslint --fix src/*.js\"\n  },\n  \"homepage\": \"https://github.com/Stryzhevskyi/rangeSlider\",\n  \"author\": {\n    \"name\": \"Serhii Stryzhevskyi\",\n    \"url\": \"https://github.com/Stryzhevskyi\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Stryzhevskyi/rangeSlider.git\"\n  },\n  \"keywords\": [\n    \"input\",\n    \"range\",\n    \"slider\",\n    \"rangeslider\",\n    \"rangeslider.js\",\n    \"polyfill\",\n    \"browser\",\n    \"pure\",\n    \"vanilla\"\n  ],\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"https://github.com/Stryzhevskyi/rangeSlider/blob/master/LICENSE.md\"\n    }\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/Stryzhevskyi/rangeSlider/issues\"\n  },\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  },\n  \"browserslist\": [\n    \"ie >= 9\",\n    \"last 3 versions\"\n  ],\n  \"devDependencies\": {\n    \"autoprefixer\": \"^10.4.27\",\n    \"cssnano\": \"^7.0.6\",\n    \"eslint\": \"^10.1.0\",\n    \"vite\": \"^8.0.1\"\n  }\n}"
  },
  {
    "path": "postcss.config.js",
    "content": "export default {\n  plugins: {\n    autoprefixer: {},\n    cssnano: {},\n  },\n};\n"
  },
  {
    "path": "src/range-slider.css",
    "content": ".rangeSlider, .rangeSlider__fill {\n    display: block;\n    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);\n    border-radius: 10px;\n}\n\n.rangeSlider {\n    position: relative;\n    background: #7f8c8d;\n}\n\n.rangeSlider__horizontal {\n    height: 20px;\n    width: 100%;\n}\n\n.rangeSlider__vertical {\n    height: 100%;\n    width: 20px;\n}\n\n.rangeSlider--disabled {\n    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);\n    opacity: 0.4;\n}\n\n.rangeSlider__fill {\n    background: #16a085;\n    position: absolute;\n}\n\n.rangeSlider__fill__horizontal {\n    height: 100%;\n    top: 0;\n    left: 0;\n}\n\n.rangeSlider__fill__vertical {\n    width: 100%;\n    bottom: 0;\n    left: 0;\n}\n\n.rangeSlider__handle {\n    border: 1px solid #ccc;\n    cursor: pointer;\n    display: inline-block;\n    width: 40px;\n    height: 40px;\n    position: absolute;\n    background: white linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.1));\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);\n    border-radius: 50%;\n}\n\n.rangeSlider__handle__horizontal {\n    top: -10px;\n}\n\n.rangeSlider__handle__vertical {\n    left: -10px;\n    bottom: 0;\n}\n\n.rangeSlider__handle:after {\n    content: \"\";\n    display: block;\n    width: 18px;\n    height: 18px;\n    margin: auto;\n    position: absolute;\n    top: 0;\n    right: 0;\n    bottom: 0;\n    left: 0;\n    background-image: linear-gradient(rgba(0, 0, 0, 0.13), rgba(255, 255, 255, 0));\n    border-radius: 50%;\n}\n\n.rangeSlider__handle:active {\n    background-image: linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.12));\n}\n\ninput[type=\"range\"]:focus + .rangeSlider .rangeSlider__handle {\n    box-shadow: 0 0 8px rgba(142, 68, 173, 0.9);\n}\n\n.rangeSlider__buffer {\n    position: absolute;\n    top: 3px;\n    height: 14px;\n    background: #2c3e50;\n    border-radius: 10px;\n}\n"
  },
  {
    "path": "src/range-slider.js",
    "content": "import * as dom from './utils/dom';\nimport * as func from './utils/functions';\nimport './range-slider.css';\n\nconst newLineAndTabRegexp = /[\\n\\t]/g;\nconst MAX_SET_BY_DEFAULT = 100;\nconst HANDLE_RESIZE_DELAY = 300;\nconst HANDLE_RESIZE_DEBOUNCE = 50;\n\nconst pluginName = 'rangeSlider';\nconst inputrange = dom.supportsRange();\nconst defaults = {\n  polyfill: true,\n  root: document,\n  rangeClass: 'rangeSlider',\n  disabledClass: 'rangeSlider--disabled',\n  fillClass: 'rangeSlider__fill',\n  bufferClass: 'rangeSlider__buffer',\n  handleClass: 'rangeSlider__handle',\n  startEvent: ['mousedown', 'touchstart', 'pointerdown'],\n  moveEvent: ['mousemove', 'touchmove', 'pointermove'],\n  endEvent: ['mouseup', 'touchend', 'pointerup'],\n  min: null,\n  max: null,\n  step: null,\n  value: null,\n  buffer: null,\n  stick: null,\n  borderRadius: 10,\n  vertical: false\n};\n\nlet verticalSlidingFixRegistered = false;\n\n/**\n * Plugin\n * @param {HTMLElement} element\n * @param {this} options\n */\nexport default class RangeSlider {\n  constructor(element, options) {\n    let minSetByDefault;\n    let maxSetByDefault;\n    let stepSetByDefault;\n    let stickAttribute;\n    let stickValues;\n\n    RangeSlider.instances.push(this);\n\n    this.element = element;\n    this.options = func.simpleExtend(defaults, options);\n    this.polyfill = this.options.polyfill;\n    this.vertical = this.options.vertical;\n    this.onInit = this.options.onInit;\n    this.onSlide = this.options.onSlide;\n    this.onSlideStart = this.options.onSlideStart;\n    this.onSlideEnd = this.options.onSlideEnd;\n    this.onSlideEventsCount = -1;\n    this.isInteractsNow = false;\n    this.needTriggerEvents = false;\n\n    this._addVerticalSlideScrollFix();\n\n    // Plugin should only be used as a polyfill\n    if (!this.polyfill) {\n      // Input range support?\n      if (inputrange) {\n        return;\n      }\n    }\n\n    this.options.buffer = this.options.buffer || parseFloat(this.element.getAttribute('data-buffer'));\n\n    this.identifier = 'js-' + pluginName + '-' + func.uuid();\n\n    this.min = func.getFirstNumberLike(\n      this.options.min,\n      parseFloat(this.element.getAttribute('min')),\n      (minSetByDefault = 0)\n    );\n\n    this.max = func.getFirstNumberLike(\n      this.options.max,\n      parseFloat(this.element.getAttribute('max')),\n      (maxSetByDefault = MAX_SET_BY_DEFAULT)\n    );\n\n    this.value = func.getFirstNumberLike(this.options.value, this.element.value,\n      parseFloat(this.element.value || this.min + (this.max - this.min) / 2));\n\n    this.step = func.getFirstNumberLike(this.options.step,\n      parseFloat(this.element.getAttribute('step')) || (stepSetByDefault = 1));\n\n    this.percent = null;\n\n    if (func.isArray(this.options.stick) && this.options.stick.length >= 1) {\n      this.stick = this.options.stick;\n    } else if ((stickAttribute = this.element.getAttribute('stick'))) {\n      stickValues = stickAttribute.split(' ');\n      if (stickValues.length >= 1) {\n        this.stick = stickValues.map(parseFloat);\n      }\n    }\n    if (this.stick && this.stick.length === 1) {\n      this.stick.push(this.step * 1.5);\n    }\n    this._updatePercentFromValue();\n\n    this.toFixed = this._toFixed(this.step);\n\n    let directionClass;\n\n    this.container = document.createElement('div');\n    dom.addClass(this.container, this.options.fillClass);\n\n    directionClass = this.vertical ? this.options.fillClass + '__vertical' : this.options.fillClass + '__horizontal';\n    dom.addClass(this.container, directionClass);\n\n    this.handle = document.createElement('div');\n    dom.addClass(this.handle, this.options.handleClass);\n\n    directionClass = this.vertical ?\n      this.options.handleClass + '__vertical' :\n      this.options.handleClass + '__horizontal';\n    dom.addClass(this.handle, directionClass);\n\n    this.range = document.createElement('div');\n    dom.addClass(this.range, this.options.rangeClass);\n    this.range.id = this.identifier;\n\n    const elementTitle = element.getAttribute('title');\n    if (elementTitle && elementTitle.length > 0) {\n      this.range.setAttribute('title', elementTitle);\n    }\n\n    if (this.options.bufferClass) {\n      this.buffer = document.createElement('div');\n      dom.addClass(this.buffer, this.options.bufferClass);\n      this.range.appendChild(this.buffer);\n\n      directionClass = this.vertical ?\n        this.options.bufferClass + '__vertical' :\n        this.options.bufferClass + '__horizontal';\n      dom.addClass(this.buffer, directionClass);\n    }\n\n    this.range.appendChild(this.container);\n    this.range.appendChild(this.handle);\n\n    directionClass = this.vertical ? this.options.rangeClass + '__vertical' : this.options.rangeClass + '__horizontal';\n    dom.addClass(this.range, directionClass);\n\n    if (func.isNumberLike(this.options.value)) {\n      this._setValue(this.options.value, true);\n      this.element.value = this.options.value;\n    }\n\n    if (func.isNumberLike(this.options.buffer)) {\n      this.element.setAttribute('data-buffer', this.options.buffer);\n    }\n\n    if (func.isNumberLike(this.options.min) || minSetByDefault) {\n      this.element.setAttribute('min', '' + this.min);\n    }\n\n    if (func.isNumberLike(this.options.max) || maxSetByDefault) {\n      this.element.setAttribute('max', '' + this.max);\n    }\n\n    if (func.isNumberLike(this.options.step) || stepSetByDefault) {\n      this.element.setAttribute('step', '' + this.step);\n    }\n\n    dom.insertAfter(this.element, this.range);\n\n    // hide the input visually\n    dom.setCss(this.element, {\n      'position': 'absolute',\n      'width': '1px',\n      'height': '1px',\n      'overflow': 'hidden',\n      'opacity': '0'\n    });\n\n    // Store context\n    this._handleDown = this._handleDown.bind(this);\n    this._handleMove = this._handleMove.bind(this);\n    this._handleEnd = this._handleEnd.bind(this);\n    this._startEventListener = this._startEventListener.bind(this);\n    this._changeEventListener = this._changeEventListener.bind(this);\n    this._handleResize = this._handleResize.bind(this);\n\n    this._init();\n\n    // Attach Events\n    window.addEventListener('resize', this._handleResize, false);\n\n    dom.addEventListeners(this.options.root, this.options.startEvent, this._startEventListener);\n\n    // Listen to programmatic value changes\n    this.element.addEventListener('change', this._changeEventListener, false);\n  }\n\n  /**\n   * A lightweight plugin wrapper around the constructor,preventing against multiple instantiations\n   * @param {Element} el\n   * @param {Object} options\n   */\n  static create(el, options) {\n    const createInstance = (el) => {\n      let data = el[pluginName];\n\n      // Create a new instance.\n      if (!data) {\n        data = new RangeSlider(el, options);\n        el[pluginName] = data;\n      }\n    };\n\n    if (el.length) {\n      Array.prototype.slice.call(el).forEach(function (el) {\n        createInstance(el);\n      });\n    } else {\n      createInstance(el);\n    }\n  }\n\n  static _touchMoveScrollHandler (event) {\n    if (RangeSlider.slidingVertically) {\n      event.preventDefault();\n    }\n  }\n\n  /* public methods */\n\n  /**\n   * @param {Object} obj like {min : Number, max : Number, value : Number, step : Number, buffer : [String|Number]}\n   * @param {Boolean} triggerEvents\n   * @returns {RangeSlider}\n   */\n  update(obj, triggerEvents) {\n    if (triggerEvents) {\n      this.needTriggerEvents = true;\n    }\n    if (func.isObject(obj)) {\n      if (func.isNumberLike(obj.min)) {\n        this.element.setAttribute('min', '' + obj.min);\n        this.min = obj.min;\n      }\n\n      if (func.isNumberLike(obj.max)) {\n        this.element.setAttribute('max', '' + obj.max);\n        this.max = obj.max;\n      }\n\n      if (func.isNumberLike(obj.step)) {\n        this.element.setAttribute('step', '' + obj.step);\n        this.step = obj.step;\n        this.toFixed = this._toFixed(obj.step);\n      }\n\n      if (func.isNumberLike(obj.buffer)) {\n        this._setBufferPosition(obj.buffer);\n      }\n\n      if (func.isNumberLike(obj.value)) {\n        this._setValue(obj.value);\n      }\n    }\n    this._update();\n    this.onSlideEventsCount = 0;\n    this.needTriggerEvents = false;\n    return this;\n  };\n\n  destroy() {\n    dom.removeAllListenersFromEl(this, this.options.root);\n    window.removeEventListener('resize', this._handleResize, false);\n    this.element.removeEventListener('change', this._changeEventListener, false);\n\n    this.element.style.cssText = '';\n    delete this.element[pluginName];\n\n    // Remove the generated markup\n    if (this.range) {\n      this.range.parentNode.removeChild(this.range);\n    }\n\n    RangeSlider.instances = RangeSlider.instances.filter((plugin) => plugin !== this);\n\n    if (!RangeSlider.instances.some((plugin) => plugin.vertical)) {\n      this._removeVerticalSlideScrollFix();\n    }\n  }\n\n  /* private methods */\n\n  _toFixed(step) {\n    return (step + '').replace('.', '').length - 1;\n  }\n\n  _init() {\n    if (this.onInit && typeof this.onInit === 'function') {\n      this.onInit();\n    }\n    this._update(false);\n  }\n\n  _updatePercentFromValue() {\n    this.percent = (this.value - this.min) / (this.max - this.min);\n  }\n\n  /**\n   * This method check if this.identifier exists in ev.target's ancestors\n   * @param ev\n   * @param data\n   */\n  _startEventListener(ev, data) {\n    const el = ev.target;\n    let isEventOnSlider = false;\n\n    if (ev.which !== 1 && !('touches' in ev)) {\n      return;\n    }\n\n    dom.forEachAncestors(\n      el,\n      el => (isEventOnSlider = el.id === this.identifier && !dom.hasClass(el, this.options.disabledClass)),\n      true\n    );\n\n    if (isEventOnSlider) {\n      this._handleDown(ev, data);\n    }\n  }\n\n  _changeEventListener(ev, data) {\n    if (data && data.origin === this.identifier) {\n      return;\n    }\n\n    const value = ev.target.value;\n    const pos = this._getPositionFromValue(value);\n\n    this._setPosition(pos);\n  }\n\n  _update(triggerEvent) {\n    const sizeProperty = this.vertical ? 'offsetHeight' : 'offsetWidth';\n\n    this.handleSize = dom.getDimension(this.handle, sizeProperty);\n    this.rangeSize = dom.getDimension(this.range, sizeProperty);\n    this.maxHandleX = this.rangeSize - this.handleSize;\n    this.grabX = this.handleSize / 2;\n    this.position = this._getPositionFromValue(this.value);\n\n    // Consider disabled state\n    if (this.element.disabled) {\n      dom.addClass(this.range, this.options.disabledClass);\n    } else {\n      dom.removeClass(this.range, this.options.disabledClass);\n    }\n\n    this._setPosition(this.position);\n    if (this.options.bufferClass && this.options.buffer) {\n      this._setBufferPosition(this.options.buffer);\n    }\n    this._updatePercentFromValue();\n    if (triggerEvent !== false) {\n      dom.triggerEvent(this.element, 'change', { origin: this.identifier });\n    }\n  }\n\n  _addVerticalSlideScrollFix() {\n    if (this.vertical && !verticalSlidingFixRegistered) {\n      document.addEventListener('touchmove', RangeSlider._touchMoveScrollHandler, { passive: false });\n      verticalSlidingFixRegistered = true;\n    }\n  }\n\n  _removeVerticalSlideScrollFix() {\n    document.removeEventListener('touchmove', RangeSlider._touchMoveScrollHandler);\n    verticalSlidingFixRegistered = false;\n  }\n\n  _handleResize() {\n    return func.debounce(() => {\n      // Simulate resizeEnd event.\n      func.delay(() => {\n        this._update();\n      }, HANDLE_RESIZE_DELAY);\n    }, HANDLE_RESIZE_DEBOUNCE)();\n  }\n\n  _handleDown(e) {\n    this.isInteractsNow = true;\n    e.preventDefault();\n    dom.addEventListeners(this.options.root, this.options.moveEvent, this._handleMove);\n    dom.addEventListeners(this.options.root, this.options.endEvent, this._handleEnd);\n\n    // If we click on the handle don't set the new position\n    if ((' ' + e.target.className + ' ').replace(newLineAndTabRegexp, ' ').indexOf(this.options.handleClass) > -1) {\n      return;\n    }\n\n    const boundingClientRect = this.range.getBoundingClientRect();\n\n    const posX = this._getRelativePosition(e);\n    const rangeX = this.vertical ? boundingClientRect.bottom : boundingClientRect.left;\n    const handleX = this._getPositionFromNode(this.handle) - rangeX;\n    const position = posX - this.grabX;\n\n    this._setPosition(position);\n\n    if (posX >= handleX && posX < handleX + this.options.borderRadius * 2) {\n      this.grabX = posX - handleX;\n    }\n    this._updatePercentFromValue();\n  }\n\n  _handleMove(e) {\n    const posX = this._getRelativePosition(e);\n\n    this.isInteractsNow = true;\n    e.preventDefault();\n    this._setPosition(posX - this.grabX);\n  }\n\n  _handleEnd(e) {\n    e.preventDefault();\n    dom.removeEventListeners(this.options.root, this.options.moveEvent, this._handleMove);\n    dom.removeEventListeners(this.options.root, this.options.endEvent, this._handleEnd);\n\n    // Ok we're done fire the change event\n    dom.triggerEvent(this.element, 'change', { origin: this.identifier });\n\n    if (this.isInteractsNow || this.needTriggerEvents) {\n      if (this.onSlideEnd && typeof this.onSlideEnd === 'function') {\n        this.onSlideEnd(this.value, this.percent, this.position);\n      }\n\n      if (this.vertical) {\n        RangeSlider.slidingVertically = false;\n      }\n    }\n    this.onSlideEventsCount = 0;\n    this.isInteractsNow = false;\n  }\n\n  _setPosition(pos) {\n    let position;\n    let stickRadius;\n    let restFromValue;\n    let stickTo;\n\n    // Snapping steps\n    let value = this._getValueFromPosition(func.between(pos, 0, this.maxHandleX));\n\n    // Stick to stick[0] in radius stick[1]\n    if (this.stick) {\n      stickTo = this.stick[0];\n      stickRadius = this.stick[1] || 0.1;\n      restFromValue = value % stickTo;\n      if (restFromValue < stickRadius) {\n        value = value - restFromValue;\n      } else if (Math.abs(stickTo - restFromValue) < stickRadius) {\n        value = value - restFromValue + stickTo;\n      }\n    }\n    position = this._getPositionFromValue(value);\n\n    // Update ui\n    if (this.vertical) {\n      this.container.style.height = (position + this.grabX) + 'px';\n      this.handle.style['webkitTransform'] = 'translateY(-' + position + 'px)';\n      this.handle.style['msTransform'] = 'translateY(-' + position + 'px)';\n      this.handle.style.transform = 'translateY(-' + position + 'px)';\n    } else {\n      this.container.style.width = (position + this.grabX) + 'px';\n      this.handle.style['webkitTransform'] = 'translateX(' + position + 'px)';\n      this.handle.style['msTransform'] = 'translateX(' + position + 'px)';\n      this.handle.style.transform = 'translateX(' + position + 'px)';\n    }\n\n    this._setValue(value);\n\n    // Update globals\n    this.position = position;\n    this.value = value;\n    this._updatePercentFromValue();\n\n    if (this.isInteractsNow || this.needTriggerEvents) {\n      if (this.onSlideStart && typeof this.onSlideStart === 'function' && this.onSlideEventsCount === 0) {\n        this.onSlideStart(this.value, this.percent, this.position);\n      }\n\n      if (this.onSlide && typeof this.onSlide === 'function') {\n        this.onSlide(this.value, this.percent, this.position);\n      }\n\n      if (this.vertical) {\n        RangeSlider.slidingVertically = true;\n      }\n    }\n\n    this.onSlideEventsCount++;\n  }\n\n  _setBufferPosition(pos) {\n    let isPercent = true;\n\n    if (isFinite(pos)) {\n      pos = parseFloat(pos);\n    } else if (func.isString(pos)) {\n      if (pos.indexOf('px') > 0) {\n        isPercent = false;\n      }\n      pos = parseFloat(pos);\n    } else {\n      console.warn('New position must be XXpx or XX%');\n      return;\n    }\n\n    if (isNaN(pos)) {\n      console.warn('New position is NaN');\n      return;\n    }\n    if (!this.options.bufferClass) {\n      console.warn('You disabled buffer, it\\'s className is empty');\n      return;\n    }\n    let bufferSize = isPercent ? pos : (pos / this.rangeSize * 100);\n\n    if (bufferSize < 0) {\n      bufferSize = 0;\n    }\n    if (bufferSize > 100) {\n      bufferSize = 100;\n    }\n    this.options.buffer = bufferSize;\n\n    let paddingSize = this.options.borderRadius / this.rangeSize * 100;\n    let bufferSizeWithPadding = bufferSize - paddingSize;\n\n    if (bufferSizeWithPadding < 0) {\n      bufferSizeWithPadding = 0;\n    }\n\n    if (this.vertical) {\n      this.buffer.style.height = bufferSizeWithPadding + '%';\n      this.buffer.style.bottom = paddingSize * 0.5 + '%';\n    } else {\n      this.buffer.style.width = bufferSizeWithPadding + '%';\n      this.buffer.style.left = paddingSize * 0.5 + '%';\n    }\n\n    this.element.setAttribute('data-buffer', bufferSize);\n  }\n\n  /**\n   *\n   * @param {Element} node\n   * @returns {*} Returns element position relative to the parent\n   * @private\n   */\n  _getPositionFromNode(node) {\n    let i = 0;\n\n    while (node !== null) {\n      i += this.vertical ? node.offsetTop : node.offsetLeft;\n      node = node.offsetParent;\n    }\n    return i;\n  }\n\n  /**\n   *\n   * @param {(MouseEvent|TouchEvent)}e\n   * @returns {number}\n   */\n  _getRelativePosition(e) {\n    const boundingClientRect = this.range.getBoundingClientRect();\n\n    // Get the offset relative to the viewport\n    const rangeSize = this.vertical ? boundingClientRect.bottom : boundingClientRect.left;\n    let pageOffset = 0;\n\n    const pagePositionProperty = this.vertical ? 'pageY' : 'pageX';\n\n    if (typeof e[pagePositionProperty] !== 'undefined') {\n      pageOffset = (e.touches && e.touches.length) ? e.touches[0][pagePositionProperty] : e[pagePositionProperty];\n    } else if (typeof e.originalEvent !== 'undefined') {\n      if (typeof e.originalEvent[pagePositionProperty] !== 'undefined') {\n        pageOffset = e.originalEvent[pagePositionProperty];\n      } else if (e.originalEvent.touches && e.originalEvent.touches[0] &&\n        typeof e.originalEvent.touches[0][pagePositionProperty] !== 'undefined') {\n        pageOffset = e.originalEvent.touches[0][pagePositionProperty];\n      }\n    } else if (e.touches && e.touches[0] && typeof e.touches[0][pagePositionProperty] !== 'undefined') {\n      pageOffset = e.touches[0][pagePositionProperty];\n    } else if (e.currentPoint && (typeof e.currentPoint.x !== 'undefined' || typeof e.currentPoint.y !== 'undefined')) {\n      pageOffset = this.vertical ? e.currentPoint.y : e.currentPoint.x;\n    }\n\n    if (this.vertical) {\n      pageOffset -= window.pageYOffset;\n    }\n\n    return this.vertical ? rangeSize - pageOffset : pageOffset - rangeSize;\n  }\n\n  _getPositionFromValue(value) {\n    const percentage = (value - this.min) / (this.max - this.min);\n    const pos = percentage * this.maxHandleX;\n\n    return isNaN(pos) ? 0 : pos;\n  }\n\n  _getValueFromPosition(pos) {\n    const percentage = ((pos) / (this.maxHandleX || 1));\n    const value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min;\n\n    return Number((value).toFixed(this.toFixed));\n  }\n\n  _setValue(value, force) {\n    if (value === this.value && !force) {\n      return;\n    }\n\n    // Set the new value and fire the `input` event\n    this.element.value = value;\n    this.value = value;\n    dom.triggerEvent(this.element, 'input', { origin: this.identifier });\n  }\n}\n\nRangeSlider.version = VERSION;\nRangeSlider.dom = dom;\nRangeSlider.functions = func;\nRangeSlider.instances = [];\nRangeSlider.slidingVertically = false;\n"
  },
  {
    "path": "src/utils/dom.js",
    "content": "import * as func from './functions';\n\nconst EVENT_LISTENER_LIST = 'eventListenerList';\n\nexport const detectIE = () => {\n  const ua = window.navigator.userAgent;\n  const msie = ua.indexOf('MSIE ');\n\n  if (msie > 0) {\n    return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);\n  }\n\n  const trident = ua.indexOf('Trident/');\n\n  if (trident > 0) {\n    const rv = ua.indexOf('rv:');\n\n    return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);\n  }\n\n  const edge = ua.indexOf('Edge/');\n\n  if (edge > 0) {\n    return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);\n  }\n\n  return false;\n};\n\nconst ieVersion = detectIE();\nconst eventCaptureParams = window.PointerEvent && !ieVersion ? {passive: false} : false;\n\n/**\n * Check if a `element` is visible in the DOM\n *\n * @param  {Element}  element\n * @return {Boolean}\n */\nexport const isHidden = (element) => (\n  element.offsetWidth === 0 || element.offsetHeight === 0 || element.open === false\n);\n\n/**\n * Get hidden parentNodes of an `element`\n *\n * @param {Element} element\n * @return {Element[]}\n */\nexport const getHiddenParentNodes = (element) => {\n  const parents = [];\n  let node = element.parentNode;\n\n  while (node && isHidden(node)) {\n    parents.push(node);\n    node = node.parentNode;\n  }\n  return parents;\n};\n\n/**\n * Returns dimensions for an element even if it is not visible in the DOM.\n *\n * @param  {Element} element\n * @param  {string}  key     (e.g. offsetWidth …)\n * @return {Number}\n */\nexport const getDimension = (element, key) => {\n  const hiddenParentNodes = getHiddenParentNodes(element);\n  const hiddenParentNodesLength = hiddenParentNodes.length;\n  const hiddenParentNodesStyle = [];\n  let dimension = element[key];\n\n  // Used for native `<details>` elements\n  const toggleOpenProperty = (element) => {\n    if (typeof element.open !== 'undefined') {\n      element.open = !element.open;\n    }\n  };\n\n  if (hiddenParentNodesLength) {\n    for (let i = 0; i < hiddenParentNodesLength; i++) {\n      // Cache the styles to restore then later.\n      hiddenParentNodesStyle.push({\n        display: hiddenParentNodes[i].style.display,\n        height: hiddenParentNodes[i].style.height,\n        overflow: hiddenParentNodes[i].style.overflow,\n        visibility: hiddenParentNodes[i].style.visibility\n      });\n\n      hiddenParentNodes[i].style.display = 'block';\n      hiddenParentNodes[i].style.height = '0';\n      hiddenParentNodes[i].style.overflow = 'hidden';\n      hiddenParentNodes[i].style.visibility = 'hidden';\n      toggleOpenProperty(hiddenParentNodes[i]);\n    }\n\n    dimension = element[key];\n\n    for (let j = 0; j < hiddenParentNodesLength; j++) {\n      toggleOpenProperty(hiddenParentNodes[j]);\n      hiddenParentNodes[j].style.display = hiddenParentNodesStyle[j].display;\n      hiddenParentNodes[j].style.height = hiddenParentNodesStyle[j].height;\n      hiddenParentNodes[j].style.overflow = hiddenParentNodesStyle[j].overflow;\n      hiddenParentNodes[j].style.visibility = hiddenParentNodesStyle[j].visibility;\n    }\n  }\n  return dimension;\n};\n\n/**\n *\n * @param {HTMLElement} el\n * @param {Object} cssObj\n * @returns {*}\n */\nexport const setCss = (el, cssObj) => {\n  for (const key in cssObj) {\n    el.style[key] = cssObj[key];\n  }\n  return el.style;\n};\n\n/**\n *\n * @param {HTMLElement} elem\n * @param {string} className\n */\nexport const hasClass = (elem, className) => new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');\n\n/**\n *\n * @param {HTMLElement} elem\n * @param {string} className\n */\nexport const addClass = (elem, className) => {\n  if (!hasClass(elem, className)) {\n    elem.className += ' ' + className;\n  }\n};\n\n/**\n *\n * @param {HTMLElement} elem\n * @param {string} className\n */\nexport const removeClass = (elem, className) => {\n  let newClass = ' ' + elem.className.replace(/[\\t\\r\\n]/g, ' ') + ' ';\n\n  if (hasClass(elem, className)) {\n    while (newClass.indexOf(' ' + className + ' ') >= 0) {\n      newClass = newClass.replace(' ' + className + ' ', ' ');\n    }\n    elem.className = newClass.replace(/^\\s+|\\s+$/g, '');\n  }\n};\n\n/**\n *\n * @param {HTMLElement} el\n * @param {Function} callback\n * @param {boolean} andForElement - apply callback for el\n * @returns {HTMLElement}\n */\nexport const forEachAncestors = (el, callback, andForElement) => {\n  if (andForElement) {\n    callback(el);\n  }\n\n  while (el.parentNode && !callback(el)) {\n    el = el.parentNode;\n  }\n\n  return el;\n};\n\n/**\n *\n * @param {HTMLElement} el\n * @param {string} name event name\n * @param {Object} data\n */\nexport const triggerEvent = (el, name, data) => {\n  if (!func.isString(name)) {\n    throw new TypeError('event name must be String');\n  }\n  if (!(el instanceof HTMLElement)) {\n    throw new TypeError('element must be HTMLElement');\n  }\n  name = name.trim();\n  const event = document.createEvent('CustomEvent');\n\n  event.initCustomEvent(name, false, false, data);\n  el.dispatchEvent(event);\n};\n\n/**\n * @param {Object} referenceNode after this\n * @param {Object} newNode insert this\n */\nexport const insertAfter = (referenceNode, newNode) =>\n  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);\n\n/**\n * Add event listeners and push them to el[EVENT_LISTENER_LIST]\n * @param {HTMLElement|Node|Document} el DOM element\n * @param {Array} events\n * @param {Function} listener\n */\nexport const addEventListeners = (el, events, listener) => {\n  events.forEach((eventName) => {\n    if (!el[EVENT_LISTENER_LIST]) {\n      el[EVENT_LISTENER_LIST] = {};\n    }\n    if (!el[EVENT_LISTENER_LIST][eventName]) {\n      el[EVENT_LISTENER_LIST][eventName] = [];\n    }\n\n    el.addEventListener(\n      eventName,\n      listener,\n      eventCaptureParams\n    );\n    if (el[EVENT_LISTENER_LIST][eventName].indexOf(listener) < 0) {\n      el[EVENT_LISTENER_LIST][eventName].push(listener);\n    }\n  });\n};\n\n/**\n * Remove event listeners and remove them from el[EVENT_LISTENER_LIST]\n * @param {HTMLElement} el DOM element\n * @param {Array} events\n * @param {Function} listener\n */\nexport const removeEventListeners = (el, events, listener) => {\n  events.forEach((eventName) => {\n    let index;\n\n    el.removeEventListener(\n      eventName,\n      listener,\n      eventCaptureParams\n    );\n\n    if (el[EVENT_LISTENER_LIST] && el[EVENT_LISTENER_LIST][eventName] &&\n      (index = el[EVENT_LISTENER_LIST][eventName].indexOf(listener)) > -1\n    ) {\n      el[EVENT_LISTENER_LIST][eventName].splice(index, 1);\n    }\n  });\n};\n\n/**\n * Remove ALL event listeners which exists in el[EVENT_LISTENER_LIST]\n * @param {RangeSlider} instance\n * @param {HTMLElement} el DOM element\n */\nexport const removeAllListenersFromEl = (instance, el) => {\n  if (!el[EVENT_LISTENER_LIST]) {\n    return;\n  }\n\n  /* jshint ignore:start */\n\n  /**\n   *\n   * @callback listener\n   * @this {Object} event name\n   */\n  function rm(listener) {\n    if (listener === instance._startEventListener) {\n      this.el.removeEventListener(this.eventName, listener, false);\n    }\n  }\n\n  for (const eventName in el[EVENT_LISTENER_LIST]) {\n    el[EVENT_LISTENER_LIST][eventName].forEach(rm, {eventName: eventName, el: el});\n  }\n\n  el[EVENT_LISTENER_LIST] = {};\n  /* jshint ignore:end */\n};\n\n/**\n * Range feature detection\n * @return {Boolean}\n */\nexport const supportsRange = () => {\n  const input = document.createElement('input');\n\n  input.setAttribute('type', 'range');\n  return input.type !== 'text';\n};\n"
  },
  {
    "path": "src/utils/functions.js",
    "content": "/**\n * Create a random uuid\n */\nexport const uuid = () => {\n  const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n};\n\n/**\n * Delays a function for the given number of milliseconds, and then calls\n * it with the arguments supplied.\n *\n * @param  {Function} fn   function\n * @param  {Number}   wait delay\n * @param  {Number}   args arguments\n * @return {Function}\n */\nexport const delay = (fn, wait, ...args) => setTimeout(() => fn.apply(null, args), wait);\n\n/**\n * Returns a debounced function that will make sure the given\n * function is not triggered too much.\n *\n * @param  {Function} fn Function to debounce.\n * @param  {Number}   debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the\n *         function. (defaults to 100ms)\n * @return {Function}\n */\nexport const debounce = (fn, debounceDuration = 100) => (...args) => {\n  if (!fn.debouncing) {\n    fn.lastReturnVal = fn.apply(window, args);\n    fn.debouncing = true;\n  }\n  clearTimeout(fn.debounceTimeout);\n  fn.debounceTimeout = setTimeout(() => {\n    fn.debouncing = false;\n  }, debounceDuration);\n  return fn.lastReturnVal;\n};\n\nexport const isString = obj => obj === '' + obj;\n\nexport const isArray = obj => Object.prototype.toString.call(obj) === '[object Array]';\n\nexport const isNumberLike = (obj) =>\n  (obj !== null && obj !== undefined && ((isString(obj) && isFinite(parseFloat(obj))) || (isFinite(obj))));\n\nexport const getFirstNumberLike = (...args) => {\n  if (!args.length) {\n    return null;\n  }\n\n  for (let i = 0, len = args.length; i < len; i++) {\n    if (isNumberLike(args[i])) {\n      return args[i];\n    }\n  }\n\n  return null;\n};\n\nexport const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]';\n\nexport const simpleExtend = (defaultOpt, options) => {\n  const opt = {};\n\n  for (let key in defaultOpt) {\n    opt[key] = defaultOpt[key];\n  }\n  for (let key in options) {\n    opt[key] = options[key];\n  }\n\n  return opt;\n};\n\nexport const between = (pos, min, max) => {\n  if (pos < min) {\n    return min;\n  }\n  if (pos > max) {\n    return max;\n  }\n  return pos;\n};\n"
  },
  {
    "path": "vite.config.js",
    "content": "import { defineConfig } from 'vite'\nimport { resolve } from 'path'\nimport pkg from './package.json'\n\nexport default defineConfig({\n  define: {\n    VERSION: JSON.stringify(pkg.version),\n  },\n  build: {\n    lib: {\n      entry: resolve(__dirname, 'src/range-slider.js'),\n      name: 'rangeSlider',\n      formats: ['umd', 'es'],\n      fileName: (format) => format === 'es' ? 'range-slider.esm.js' : 'range-slider.js',\n      cssFileName: 'range-slider',\n    },\n    sourcemap: true,\n    cssCodeSplit: false,\n  },\n  server: {\n    port: 8000,\n    open: '/example/index-esm.html',\n  },\n})\n"
  }
]