(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
  typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Vue3SeamlessScroll = {}, global.Vue));
})(this, (function (exports, vue) { 'use strict';

  function throttle(delay, func) {
    let lastCall = 0;
    return function (...args) {
      const now = Date.now();
      if (now - lastCall >= delay) {
        lastCall = now;
        func.apply(this, args);
      }
    };
  }

  function generateUUID() {
    const template = 'xxxxxxxxxxxxaxxxyxxxxxxxxxxxxxxx';
    return template.replace(/[xy]/g, function (char) {
      const random = Math.random() * 16 | 0;
      const value = char === 'x' ? random : (random & 0x3) | 0x8;
      return value.toString(16);
    });
  }

  const uuid = () => {
    return generateUUID().replaceAll('-', '');
  };

  function duplicateId(list) {
    const seen = new Set();
    const duplicates = new Set();

    list.forEach(item => {
      if (seen.has(item.id)) {
        duplicates.add(item);
      } else {
        seen.add(item.id);
      }
    });
    if (duplicates.size > 0) {
      list.forEach(item => {
        item.id = uuid();
      });
    }

    return list;
  }

  /**
   * 
   * @param {Array} list 
   * @returns {Array}
   */
  function listMap(list) {
    return list.map((data, index) => {
      return {
        id: uuid(),
        index,
        data
      }
    })
  }

  var script$2 = vue.defineComponent({
    name: 'VerticalScroll',
    emits: ['offset', 'count'],
    inheritAttrs: false,
    props: {
      // 是否开启自动滚动
      modelValue: {
        type: Boolean,
        default: true,
      },
      list: {
        type: Array,
        required: true,
      },
      // 是否开启鼠标悬停
      hover: {
        type: Boolean,
        default: false,
      },
      // 单步停止等待时间 (默认值 1000ms)
      singleWaitTime: {
        type: Number,
        default: 1000,
      },
      // 开启鼠标悬停时支持滚轮滚动
      wheel: {
        type: Boolean,
        default: false,
      },
      // 启用单行滚动
      singleLine: {
        type: Boolean,
        default: false,
      },
      step: {
        type: Number,
        default: 0.5,
      },
      visibleCount: {
        type: Number,
      },
      ease: {
        type: String,
        default: 'cubic-bezier(0.03, 0.76, 1, 0.16)'
      },
      direction: {
        type: String,
        default: 'up',
      },
      delay: {
        type: Number,
        default: 0,
      }
    },
    setup(props, { expose, emit }) {
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperRef = vue.ref(null);
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperHiddenRef = vue.ref(null);

      const funArgs = vue.ref([]);

      const offset = vue.ref(0);

      const isHover = vue.ref(false);

      const direction = vue.ref(props.direction);

      const isScroll = vue.computed(() => props.hover ? !isHover.value && props.modelValue : props.modelValue);

      const testList = vue.ref([]);

      const targetList = listMap(props.list);

      const visibleCount = vue.ref(props.visibleCount === (undefined) ? 0 : props.visibleCount);

      let total = 0;

      let count = 0;

      let totalCount = 0;

      let childrenHeightList = [];

      let bufferTotalHeight = 0;

      let bufferSize = 0;

      let cursorIndex = -1;

      let realBoxHeight = 0;

      let reqFrame = null;

      let singleState = false;

      let singleOffset = 0;

      let tempOffset = 0;

      let listCanScroll = false;

      const cancle = () => {
        cancelAnimationFrame(reqFrame);
        reqFrame = null;
      };

      const updateCursorIndex = () => {
        const totalIndex = cursorIndex + bufferSize;
        if (totalIndex >= targetList.length) {
          const tempIndex = totalIndex - targetList.length;
          const tempFuns = ['splice',
            [0, bufferSize],
            [cursorIndex],
            [0, tempIndex]];
          funArgs.value = tempFuns;
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
        } else {
          const tempFuns = ['splice', [0, bufferSize], [cursorIndex, totalIndex]];
          funArgs.value = tempFuns;
          cursorIndex = totalIndex;
        }
      };

      const initHeight = () => {
        const children = Array.from(realWrapperRef.value.children);
        const subChildren = direction.value === 'up' ?
          children.slice(0, bufferSize) :
          children.slice(visibleItems.value.length - bufferSize, visibleItems.value.length);
        childrenHeightList = subChildren.map((c) => c.offsetHeight);
        bufferTotalHeight = childrenHeightList
          .reduce((a, b) => a + b, 0);
      };

      const animation = (isWheel, step) => {
        cancle();
        if (!listCanScroll) {
          return;
        }

        const scrollFun = () => {
          const singleHeight = childrenHeightList[0];
          let singleDone = false;
          if (singleOffset >= singleHeight) {
            singleDone = true;
          }

          if (singleDone) {
            childrenHeightList.shift();
            singleOffset = 0;
            count += 1;
          }
          if (count === total) {
            totalCount += 1;
            emit('count', totalCount);
            count = 0;
          }

          if (props.singleLine && singleDone) {
            singleState = true;
            setTimeout(() => {
              singleState = false;
              if (!isWheel) {
                animation(false, props.step);
              }
            }, props.singleWaitTime);
          } else {
            if (!isWheel) {
              animation(false, props.step);
            }
          }
        };
        if (isScroll.value && !singleState || isWheel) {
          reqFrame = requestAnimationFrame(() => {
            tempOffset += step;
            singleOffset += step;
            if (direction.value === 'up') {
              offset.value += step;
            } else {
              offset.value -= step;
            }
            if (tempOffset > bufferTotalHeight) {
              emit('offset', bufferSize, targetList);
              updateCursorIndex();
              vue.nextTick(() => {
                offset.value = direction.value === 'up' ? 0 : getFullHeight() - realBoxHeight;
                tempOffset = 0;
                initHeight();
                scrollFun();
              });
            } else {
              scrollFun();
            }
          });
        }
      };

      const onMouseenter = () => {
        isHover.value = true;
      };

      const onMouseleave = () => {
        isHover.value = false;
        if (props.hover) {
          animation(false, props.step);
        }
      };

      const throttleFunc = throttle(30, (e) => {
        animation(true, 10);
      });

      const onWheel = (e) => {
        if (props.hover && props.wheel) {
          throttleFunc(e);
          e.preventDefault();
          e.stopPropagation();
        }
      };

      /**
       * @type {import('vue').ComputedRef<Array<any>>}
       */
      const visibleItems = vue.computed(() => {
        let tempList = [];
        if (funArgs.value.length === 0) {
          tempList = targetList.slice(0, visibleCount.value);
        } else if (funArgs.value[0] === 'splice') {
          tempList = direction.value === 'up' ? visibleItems.value : visibleItems.value.reverse();
          tempList.splice(...funArgs.value[1]);
          funArgs.value.slice(2).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        } else {
          funArgs.value.slice(1).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        }
        if (!(direction.value === 'up')) {
          tempList.reverse();
        }
        return duplicateId(tempList);
      });

      const initCursorIndex = () => {
        cursorIndex = visibleCount.value + bufferSize;
        if (cursorIndex >= targetList.length) {
          const tempIndex = cursorIndex - targetList.length;
          const tempFunArgs = ['slice', [0, cursorIndex], [0, tempIndex]];
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
          return tempFunArgs;
        } else {
          return ['slice', [0, cursorIndex]];
        }
      };


      const getFullHeight = () => {
        return Array.from(realWrapperRef.value.children)
          .map((c) => c.offsetHeight).reduce((a, b) => a + b, 0);
      };

      const initVisibleCount = (cb) => {
        if (props.visibleCount === (undefined)) {
          testList.value = listMap([props.list[0]]);
          vue.nextTick(() => {
            visibleCount.value = Math.ceil(realBoxHeight / realWrapperHiddenRef.value.offsetHeight) + 2;
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              cb();
            });
          });
        } else {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            cb();
          });
        }
      };

      vue.onMounted(() => {
        if (!!realWrapperRef.value) {
          realWrapperRef.value.parentElement.addEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.addEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.addEventListener('wheel', onWheel);
          realBoxHeight = realWrapperRef.value.parentElement.offsetHeight;

          if (props.list.length > 0) {
            initVisibleCount(() => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxHeight;
              if (hasVerticalScroll) {
                bufferSize = getBufferSize();

                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  offset.value = direction.value === 'up' ? 0 : getFullHeight() - realBoxHeight;

                  initHeight();
                  listCanScroll = true;
                  setTimeout(() => {
                    animation(false, props.step);
                  }, props.delay);
                });
              } else {
                init();
              }
              testList.value = [];
            });
          }
        }
        total = targetList.length;
      });

      const init = () => {
        count = 0;
        totalCount = 0;
        listCanScroll = false;
        bufferSize = 0;
        funArgs.value = [];
        vue.nextTick(() => {
          offset.value = direction.value === 'up' ? 0 : getFullHeight() - realBoxHeight;
          tempOffset = 0;
          singleOffset = 0;
        });
      };

      const getBufferSize = () => {
        let tempBufferSize = targetList.length - visibleCount.value;
        tempBufferSize = Math.max(1, tempBufferSize);
        tempBufferSize = Math.min(5, tempBufferSize);
        return tempBufferSize;
      };

      const add = (index, values, cb) => {
        if (!!values && values.length > 0) {
          if (index > targetList.length) {
            index = targetList.length;
          }
          if (index < 0) {
            index = 0;
          }
          const findIndexs = [];
          if (values.length === 1) {
            visibleItems.value.forEach((v, i) => {
              if (v.index === index) {
                findIndexs.push(i);
              }
            });
          }
          const datas = [];
          values.forEach((v) => {
            datas.push({
              id: uuid(),
              data: v
            });
          });

          targetList.splice(index, 0, ...datas);
          targetList.forEach((v, i) => {
            v.index = i;
          });

          const tempBufferSize = getBufferSize();

          if (listCanScroll) {
            if (index < cursorIndex) {
              cursorIndex += 1;
              if (cursorIndex > targetList.length) {
                cursorIndex = 0;
              }
            }

            if (values.length === 1 && findIndexs.length > 0) {
              findIndexs.forEach((i) => {
                visibleItems.value[i] = datas[0];
              });
            }
            if (tempBufferSize !== bufferSize) {
              bufferSize = tempBufferSize;
            }
          } else {
            const fun = () => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxHeight;
              if (hasVerticalScroll) {
                bufferSize = tempBufferSize;
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  offset.value = direction.value === 'up' ? 0 : getFullHeight() - realBoxHeight;
                  tempOffset = 0;
                  singleOffset = 0;

                  initHeight();
                  listCanScroll = true;
                  animation(false, props.step);
                });
              } else {
                if (props.visibleCount === (undefined)) {
                  visibleCount.value = 0;
                }
                init();
              }
              testList.value = [];
            };
            if (visibleCount.value === 0 && props.visibleCount === (undefined)) {
              initVisibleCount(() => {
                fun();
              });
            } else {
              testList.value = targetList.slice(0, visibleCount.value);
              vue.nextTick(() => {
                fun();
              });
            }
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };

      const remove = (index, num = 1, cb) => {
        if (index >= 0 && index < targetList.length) {
          targetList.splice(index, num);
          if (listCanScroll) {
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxHeight;
              if (hasVerticalScroll) {
                const tempBufferSize = getBufferSize();
                if (tempBufferSize !== bufferSize) {
                  bufferSize = tempBufferSize;
                }
                funArgs.value = initCursorIndex();
              } else {
                init();
              }
              testList.value = [];
            });
          } else {
            init();
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };


      const reset = () => {
        vue.nextTick(() => {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            const hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxHeight;
            if (hasVerticalScroll) {
              if (funArgs.value[0] === 'splice') {
                updateCursorIndex();
                vue.nextTick(() => {
                  initHeight();
                });
              } else {
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  initHeight();
                });
              }
            } else {
              init();
            }
          });
        });
      };


      const update = (index, value, cb) => {
        if (index >= 0 && index < targetList.length) {
          const findIndexs = [];
          visibleItems.value.forEach((v, i) => {
            if (v.index === index) {
              findIndexs.push(i);
            }
          });
          const data = {
            id: uuid(),
            index: index,
            data: value
          };
          targetList[index] = data;
          if (findIndexs.length > 0) {
            findIndexs.forEach((i) => {
              visibleItems.value[i] = data;
            });
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
      };

      expose({ add, remove, update, reset });

      vue.watch(() => props.modelValue, (val) => {
        if (val) {
          animation(false, props.step);
        }
      });

      vue.onUnmounted(() => {
        cancelAnimationFrame(reqFrame);
        if (realWrapperRef.value) {
          realWrapperRef.value.parentElement.removeEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.removeEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.removeEventListener('wheel', onWheel);
        }
      });

      return {
        realWrapperRef,
        visibleItems,
        offset,
        testList,
        realWrapperHiddenRef
      }
    }
  });

  const _hoisted_1 = {
    style: {"position":"absolute !important","top":"-999999px !important"},
    ref: "realWrapperHiddenRef"
  };

  function render$2(_ctx, _cache, $props, $setup, $data, $options) {
    return (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
      vue.createElementVNode("div", {
        class: "vue3-seamless-vertical-wrapper",
        ref: "realWrapperRef",
        style: vue.normalizeStyle({ transition: `transform ${_ctx.ease}`, transform: `translateY(-${_ctx.offset}px)` })
      }, [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.visibleItems, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 4 /* STYLE */),
      vue.createElementVNode("div", _hoisted_1, [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.testList, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 512 /* NEED_PATCH */)
    ], 64 /* STABLE_FRAGMENT */))
  }

  function styleInject(css, ref) {
    if ( ref === undefined ) ref = {};
    var insertAt = ref.insertAt;

    if (!css || typeof document === 'undefined') { return; }

    var head = document.head || document.getElementsByTagName('head')[0];
    var style = document.createElement('style');
    style.type = 'text/css';

    if (insertAt === 'top') {
      if (head.firstChild) {
        head.insertBefore(style, head.firstChild);
      } else {
        head.appendChild(style);
      }
    } else {
      head.appendChild(style);
    }

    if (style.styleSheet) {
      style.styleSheet.cssText = css;
    } else {
      style.appendChild(document.createTextNode(css));
    }
  }

  var css_248z$2 = "\n.vue3-seamless-vertical-wrapper[data-v-70134dc7] {\r\n  width: 100%;\n}\r\n";
  styleInject(css_248z$2);

  script$2.render = render$2;
  script$2.__scopeId = "data-v-70134dc7";
  script$2.__file = "packages/VerticalScroll.vue";

  var script$1 = vue.defineComponent({
    name: 'HorizontalScroll',
    emits: ['offset', 'count'],
    inheritAttrs: false,
    props: {
      // 是否开启自动滚动
      modelValue: {
        type: Boolean,
        default: true,
      },
      list: {
        type: Array,
        required: true,
      },
      // 是否开启鼠标悬停
      hover: {
        type: Boolean,
        default: false,
      },
      // 单步停止等待时间 (默认值 1000ms)
      singleWaitTime: {
        type: Number,
        default: 1000,
      },
      // 开启鼠标悬停时支持滚轮滚动
      wheel: {
        type: Boolean,
        default: false,
      },
      // 启用单行滚动
      singleLine: {
        type: Boolean,
        default: false,
      },
      step: {
        type: Number,
        default: 0.5,
      },
      visibleCount: {
        type: Number,
      },
      ease: {
        type: String,
        default: 'cubic-bezier(0.03, 0.76, 1, 0.16)'
      },
      direction: {
        type: String,
        default: 'left',
      },
      delay: {
        type: Number,
        default: 0,
      }
    },
    setup(props, { emit, expose }) {
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperRef = vue.ref(null);
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperHiddenRef = vue.ref(null);

      const funArgs = vue.ref([]);

      const offset = vue.ref(0);

      const isHover = vue.ref(false);

      const direction = vue.ref(props.direction);

      const isScroll = vue.computed(() => props.hover ? !isHover.value && props.modelValue : props.modelValue);

      const testList = vue.ref([]);

      const visibleCount = vue.ref(props.visibleCount === (undefined) ? 0 : props.visibleCount);

      const targetList = listMap(props.list);

      let total = 0;

      let count = 0;

      let totalCount = 0;

      let childrenWidthList = [];

      let bufferTotalWidth = 0;

      let bufferSize = 0;

      let cursorIndex = -1;

      let realBoxWidth = 0;

      let reqFrame = null;

      let singleState = false;

      let singleOffset = 0;

      let tempOffset = 0;

      let listCanScroll = false;

      const cancle = () => {
        cancelAnimationFrame(reqFrame);
        reqFrame = null;
      };

      const updateCursorIndex = () => {
        const totalIndex = cursorIndex + bufferSize;
        if (totalIndex >= targetList.length) {
          const tempIndex = totalIndex - targetList.length;
          const tempFuns = ['splice',
            [0, bufferSize],
            [cursorIndex],
            [0, tempIndex]];
          funArgs.value = tempFuns;
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
        } else {
          const tempFuns = ['splice', [0, bufferSize], [cursorIndex, totalIndex]];
          funArgs.value = tempFuns;
          cursorIndex = totalIndex;
        }
      };

      const initWidth = () => {
        const children = Array.from(realWrapperRef.value.children);
        const subChildren = direction.value === 'left' ?
          children.slice(0, bufferSize) :
          children.slice(visibleItems.value.length - bufferSize, visibleItems.value.length);

        childrenWidthList = subChildren.map((c) => c.offsetWidth);
        bufferTotalWidth = childrenWidthList
          .reduce((a, b) => a + b, 0);
      };

      const animation = (isWheel, step) => {
        cancle();
        if (!listCanScroll) {
          return;
        }

        const scrollFun = () => {
          const singleWidth = childrenWidthList[0];
          let singleDone = false;
          if (singleOffset >= singleWidth) {
            singleDone = true;
          }

          if (singleDone) {
            childrenWidthList.shift();
            singleOffset = 0;
            count += 1;
          }
          if (count === total) {
            totalCount += 1;
            emit('count', totalCount);
            count = 0;
          }

          if (props.singleLine && singleDone) {
            singleState = true;
            setTimeout(() => {
              singleState = false;
              if (!isWheel) {
                animation(false, props.step);
              }
            }, props.singleWaitTime);
          } else {
            if (!isWheel) {
              animation(false, props.step);
            }
          }
        };
        if (isScroll.value && !singleState || isWheel) {
          reqFrame = requestAnimationFrame(() => {
            tempOffset += step;
            singleOffset += step;
            if (props) {
              offset.value += step;
            } else {
              offset.value -= step;
            }
            if (tempOffset > bufferTotalWidth) {
              emit('offset', bufferSize, targetList);
              updateCursorIndex();
              vue.nextTick(() => {
                offset.value = direction.value === 'left' ? 0 : getFullWidth() - realBoxWidth;
                tempOffset = 0;
                initWidth();
                scrollFun();
              });
            } else {
              scrollFun();
            }
          });
        }
      };

      const onMouseenter = () => {
        isHover.value = true;
      };

      const onMouseleave = () => {
        isHover.value = false;
        if (props.hover) {
          animation(false, props.step);
        }
      };

      const throttleFunc = throttle(30, (e) => {
        animation(true, 10);
      });

      const onWheel = (e) => {
        if (props.hover && props.wheel) {
          throttleFunc(e);
          e.preventDefault();
          e.stopPropagation();
        }
      };

      /**
      * @type {import('vue').ComputedRef<Array<any>>}
      */
      const visibleItems = vue.computed(() => {
        let tempList = [];
        if (funArgs.value.length === 0) {
          tempList = targetList.slice(0, visibleCount.value);
        } else if (funArgs.value[0] === 'splice') {
          tempList = direction.value === 'left' ? visibleItems.value : visibleItems.value.reverse();
          tempList.splice(...funArgs.value[1]);
          funArgs.value.slice(2).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        } else {
          funArgs.value.slice(1).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        }
        if (!(direction.value === 'left')) {
          tempList.reverse();
        }
        return duplicateId(tempList);
      });

      const initCursorIndex = () => {
        cursorIndex = visibleCount.value + bufferSize;
        if (cursorIndex >= targetList.length) {
          const tempIndex = cursorIndex - targetList.length;
          const tempFunArgs = ['slice', [0, cursorIndex], [0, tempIndex]];
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
          return tempFunArgs;
        } else {
          return ['slice', [0, cursorIndex]];
        }
      };

      const getFullWidth = () => {
        return Array.from(realWrapperRef.value.children)
          .map((c) => c.offsetWidth).reduce((a, b) => a + b, 0);
      };

      const initVisibleCount = (cb) => {
        if (props.visibleCount === (undefined)) {
          testList.value = listMap([props.list[0]]);
          vue.nextTick(() => {
            visibleCount.value = Math.ceil(realBoxWidth / realWrapperHiddenRef.value.offsetWidth) + 2;
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              cb();
            });
          });
        } else {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            cb();
          });
        }
      };

      vue.onMounted(() => {
        if (!!realWrapperRef.value) {
          realWrapperRef.value.parentElement.addEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.addEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.addEventListener('wheel', onWheel);
          realBoxWidth = realWrapperRef.value.parentElement.offsetWidth;

          if (props.list.length > 0) {
            initVisibleCount(() => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWidth;
              if (hasVerticalScroll) {
                bufferSize = getBufferSize();
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  offset.value = direction.value === 'left' ? 0 : getFullWidth() - realBoxWidth;
                  initWidth();
                  listCanScroll = true;
                  setTimeout(() => {
                    animation(false, props.step);
                  }, props.delay);
                });
              } else {
                init();
              }
              testList.value = [];
            });
          }
        }
        total = targetList.length;
      });

      const init = () => {
        count = 0;
        totalCount = 0;
        listCanScroll = false;
        bufferSize = 0;
        funArgs.value = [];
        vue.nextTick(() => {
          offset.value = direction.value === 'left' ? 0 : getFullWidth() - realBoxWidth;
          tempOffset = 0;
          singleOffset = 0;
        });
      };

      const getBufferSize = () => {
        let tempBufferSize = targetList.length - visibleCount.value;
        tempBufferSize = Math.max(1, tempBufferSize);
        tempBufferSize = Math.min(5, tempBufferSize);
        return tempBufferSize;
      };

      const add = (index, values, cb) => {
        if (!!values && values.length > 0) {
          if (index > targetList.length) {
            index = targetList.length;
          }
          if (index < 0) {
            index = 0;
          }
          const findIndexs = [];
          if (values.length === 1) {
            visibleItems.value.forEach((v, i) => {
              if (v.index === index) {
                findIndexs.push(i);
              }
            });
          }
          const datas = [];
          values.forEach((v) => {
            datas.push({
              id: uuid(),
              data: v
            });
          });

          targetList.splice(index, 0, ...datas);
          targetList.forEach((v, i) => {
            v.index = i;
          });

          const tempBufferSize = getBufferSize();

          if (listCanScroll) {
            if (index < cursorIndex) {
              cursorIndex += 1;
              if (cursorIndex > targetList.length) {
                cursorIndex = 0;
              }
            }
            if (values.length === 1) {
              findIndexs.forEach((i) => {
                visibleItems.value[i] = datas[0];
              });
            }
            if (tempBufferSize !== bufferSize) {
              bufferSize = tempBufferSize;
            }
          } else {
            const fun = () => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWidth;
              if (hasVerticalScroll) {
                bufferSize = tempBufferSize;
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  offset.value = direction.value === 'left' ? 0 : getFullWidth() - realBoxWidth;
                  tempOffset = 0;
                  singleOffset = 0;

                  initWidth();
                  listCanScroll = true;
                  animation(false, props.step);
                });
              } else {
                if (props.visibleCount === (undefined)) {
                  visibleCount.value = 0;
                }
                init();
              }
              testList.value = [];
            };

            if (visibleCount.value === 0 && props.visibleCount === (undefined)) {
              initVisibleCount(() => {
                fun();
              });
            } else {
              testList.value = targetList.slice(0, visibleCount.value);
              vue.nextTick(() => {
                fun();
              });
            }
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };

      const remove = (index, num = 1, cb) => {
        if (index >= 0 && index < targetList.length) {
          targetList.splice(index, num);
          if (listCanScroll) {
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              const hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWidth;
              if (hasVerticalScroll) {
                const tempBufferSize = getBufferSize();

                if (tempBufferSize !== bufferSize) {
                  bufferSize = tempBufferSize;
                }
                funArgs.value = initCursorIndex();
              } else {
                init();
              }
              testList.value = [];
            });
          } else {
            init();
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };


      const reset = () => {
        vue.nextTick(() => {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            const hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWidth;
            if (hasVerticalScroll) {
              if (funArgs.value[0] === 'splice') {
                updateCursorIndex();
                vue.nextTick(() => {
                  initWidth();
                });
              } else {
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  initWidth();
                });
              }
            } else {
              init();
            }
          });
        });
      };


      const update = (index, value, cb) => {
        if (index >= 0 && index < targetList.length) {
          const findIndexs = [];
          visibleItems.value.forEach((v, i) => {
            if (v.index === index) {
              findIndexs.push(i);
            }
          });
          const data = {
            id: uuid(),
            index: index,
            data: value
          };
          targetList[index] = data;
          if (findIndexs.length > 0) {
            findIndexs.forEach((i) => {
              visibleItems[i] = data;
            });
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
      };

      expose({ add, remove, update, reset });

      vue.watch(() => props.modelValue, (val) => {
        if (val) {
          animation(false, props.step);
        }
      });

      vue.onUnmounted(() => {
        cancelAnimationFrame(reqFrame);
        if (!!realWrapperRef.value) {
          realWrapperRef.value.parentElement.removeEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.removeEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.removeEventListener('wheel', onWheel);
        }
      });

      return {
        visibleItems,
        offset,
        testList,
        realWrapperRef,
        realWrapperHiddenRef
      }
    }
  });

  function render$1(_ctx, _cache, $props, $setup, $data, $options) {
    return (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
      vue.createElementVNode("div", vue.mergeProps({
        class: "vue3-seamless-horizontal-wrapper",
        ref: "realWrapperRef",
        style: { transition: `transform ${_ctx.ease}`, transform: `translateX(-${_ctx.offset}px)` }
      }, _ctx.$attrs), [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.visibleItems, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index,
            style: "color: brown;"
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 16 /* FULL_PROPS */),
      vue.createElementVNode("div", vue.mergeProps({
        style: {"position":"absolute !important","top":"-999999px !important"},
        ref: "realWrapperHiddenRef"
      }, _ctx.$attrs), [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.testList, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 16 /* FULL_PROPS */)
    ], 64 /* STABLE_FRAGMENT */))
  }

  var css_248z$1 = "\n.vue3-seamless-horizontal-wrapper[data-v-530d6df5] {\n  height: 100%;\n}\n";
  styleInject(css_248z$1);

  script$1.render = render$1;
  script$1.__scopeId = "data-v-530d6df5";
  script$1.__file = "packages/HorizontalScroll.vue";

  var script = vue.defineComponent({
    name: 'Vue3SeamlessScroll',
    emits: ['offset', 'count'],
    inheritAttrs: false,
    props: {
      // 是否开启自动滚动
      modelValue: {
        type: Boolean,
        default: true,
      },
      list: {
        type: Array,
        required: true,
      },
      // 是否开启鼠标悬停
      hover: {
        type: Boolean,
        default: false,
      },
      // 单步停止等待时间 (默认值 1000ms)
      singleWaitTime: {
        type: Number,
        default: 1000,
      },
      // 开启鼠标悬停时支持滚轮滚动
      wheel: {
        type: Boolean,
        default: false,
      },
      // 启用单行滚动
      singleLine: {
        type: Boolean,
        default: false,
      },
      step: {
        type: Number,
        default: 0.5,
      },
      visibleCount: {
        type: Number,
      },
      ease: {
        type: String,
        default: 'cubic-bezier(0.03, 0.76, 1, 0.16)'
      },
      // up，down，left，right
      direction: {
        type: String,
        default: 'up',
      },
      delay: {
        type: Number,
        default: 0,
      }
    },
    setup(props, { expose, emit }) {
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realBoxRef = vue.ref(null);
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperRef = vue.ref(null);
      /**
      * @type {import('vue').Ref<HTMLDivElement>}
      */
      const realWrapperHiddenRef = vue.ref(null);

      const funArgs = vue.ref([]);

      const offset = vue.ref(0);

      const isHover = vue.ref(false);

      const direction = vue.ref(props.direction);

      const isScroll = vue.computed(() => props.hover ? !isHover.value && props.modelValue : props.modelValue);

      const testList = vue.ref([]);

      const visibleCount = vue.ref(props.visibleCount === (undefined) ? 0 : props.visibleCount);

      const targetList = listMap(props.list);

      let total = 0;

      let count = 0;

      let totalCount = 0;

      let childrenWHList = [];

      let bufferTotalWH = 0;

      let bufferSize = 0;

      let cursorIndex = -1;

      let realBoxWH = 0;

      let reqFrame = null;

      let singleState = false;

      let singleOffset = 0;

      let tempOffset = 0;

      let listCanScroll = false;

      const transform = vue.computed(() => {
        if (direction.value === 'up' || direction.value === 'down') {
          return `translateY(-${offset.value}px)`;
        }
        return `translateX(-${offset.value}px)`;
      });

      const cancle = () => {
        cancelAnimationFrame(reqFrame);
        reqFrame = null;
      };

      const updateCursorIndex = () => {
        const totalIndex = cursorIndex + bufferSize;
        if (totalIndex >= targetList.length) {
          const tempIndex = totalIndex - targetList.length;
          const tempFuns = ['splice',
            [0, bufferSize],
            [cursorIndex],
            [0, tempIndex]];
          funArgs.value = tempFuns;
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
        } else {
          const tempFuns = ['splice', [0, bufferSize], [cursorIndex, totalIndex]];
          funArgs.value = tempFuns;
          cursorIndex = totalIndex;
        }
      };

      const initWH = () => {
        const children = Array.from(realWrapperRef.value.children);
        const subChildren = (direction.value === 'up' || direction.value === 'left') ?
          children.slice(0, bufferSize) :
          children.slice(visibleItems.value.length - bufferSize, visibleItems.value.length);

        childrenWHList = subChildren.map((c) => {
          if (direction.value === 'left' || direction.value === 'right') {
            return c.offsetWidth;
          } else {
            return c.offsetHeight;
          }
        });
        bufferTotalWH = childrenWHList
          .reduce((a, b) => a + b, 0);
      };

      const updateOffset = () => {
        if (direction.value === 'up' || direction.value === 'left') {
          offset.value = 0;
        } else {
          offset.value = getFullWH() - realBoxWH;
        }
      };

      const animation = (isWheel, step) => {
        cancle();
        if (!listCanScroll) {
          return;
        }

        const scrollFun = () => {
          const singleWH = childrenWHList[0];
          let singleDone = false;
          if (singleOffset >= singleWH) {
            singleDone = true;
          }

          if (singleDone) {
            childrenWHList.shift();
            singleOffset = 0;
            count += 1;
          }
          if (count === total) {
            totalCount += 1;
            emit('count', totalCount);
            count = 0;
          }

          if (props.singleLine && singleDone) {
            singleState = true;
            setTimeout(() => {
              singleState = false;
              if (!isWheel) {
                animation(false, props.step);
              }
            }, props.singleWaitTime);
          } else {
            if (!isWheel) {
              animation(false, props.step);
            }
          }
        };
        if (isScroll.value && !singleState || isWheel) {
          reqFrame = requestAnimationFrame(() => {
            tempOffset += step;
            singleOffset += step;
            if (direction.value === 'up' || direction.value === 'left') {
              offset.value += step;
            } else {
              offset.value -= step;
            }
            if (tempOffset > bufferTotalWH) {
              emit('offset', bufferSize, targetList);
              updateCursorIndex();
              vue.nextTick(() => {
                updateOffset();
                tempOffset = 0;
                initWH();
                scrollFun();
              });
            } else {
              scrollFun();
            }
          });
        }
      };

      const onMouseenter = () => {
        isHover.value = true;
      };

      const onMouseleave = () => {
        isHover.value = false;
        if (props.hover) {
          animation(false, props.step);
        }
      };

      const throttleFunc = throttle(30, (e) => {
        animation(true, 10);
      });

      const onWheel = (e) => {
        if (props.hover && props.wheel) {
          throttleFunc(e);
          e.preventDefault();
          e.stopPropagation();
        }
      };

      /**
       * @type {import('vue').ComputedRef<Array<any>>}
       */
      const visibleItems = vue.computed(() => {
        let tempList = [];
        if (funArgs.value.length === 0) {
          tempList = targetList.slice(0, visibleCount.value);
        } else if (funArgs.value[0] === 'splice') {
          tempList = (direction.value === 'up' || direction.value === 'left') ? visibleItems.value : visibleItems.value.reverse();
          tempList.splice(...funArgs.value[1]);
          funArgs.value.slice(2).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        } else {
          funArgs.value.slice(1).forEach(args => {
            tempList.push(...targetList.slice(...args));
          });
        }
        if (!((direction.value === 'up' || direction.value === 'left'))) {
          tempList.reverse();
        }
        return duplicateId(tempList);
      });

      const initCursorIndex = () => {
        cursorIndex = visibleCount.value + bufferSize;
        if (cursorIndex >= targetList.length) {
          const tempIndex = cursorIndex - targetList.length;
          const tempFunArgs = ['slice', [0, cursorIndex], [0, tempIndex]];
          if (tempIndex > targetList.length) {
            cursorIndex = targetList.length;
          } else {
            cursorIndex = tempIndex;
          }
          return tempFunArgs;
        } else {
          return ['slice', [0, cursorIndex]];
        }
      };

      const getFullWH = () => {
        const wh = Array.from(realWrapperRef.value.children)
          .map((c) => {
            if (direction.value === 'left' || direction.value === 'right') {
              return c.offsetWidth;
            } else {
              return c.offsetHeight;
            }
          }).reduce((a, b) => a + b, 0);
        return wh;
      };

      const initVisibleCount = (cb) => {
        if (props.visibleCount === (undefined)) {
          testList.value = listMap([props.list[0]]);
          vue.nextTick(() => {
            if (direction.value === 'left' || direction.value === 'right') {
              visibleCount.value = Math.ceil(realBoxWH / realWrapperHiddenRef.value.offsetWidth) + 2;
            } else {
              visibleCount.value = Math.ceil(realBoxWH / realWrapperHiddenRef.value.offsetHeight) + 2;
            }
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              cb();
            });
          });
        } else {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            cb();
          });
        }
      };

      vue.onMounted(() => {
        if (!!realWrapperRef.value) {
          realWrapperRef.value.parentElement.addEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.addEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.addEventListener('wheel', onWheel);

          realBoxWH = realWrapperRef.value.parentElement.offsetHeight;
          if (direction.value === 'left' || direction.value === 'right') {
            realBoxWH = realWrapperRef.value.parentElement.offsetWidth;
          }

          initVisibleCount(() => {
            let hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxWH;
            if (direction.value === 'left' || direction.value === 'right') {
              hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWH;
            }
            if (hasVerticalScroll) {
              bufferSize = getBufferSize();

              funArgs.value = initCursorIndex();
              vue.nextTick(() => {
                updateOffset();

                initWH();
                listCanScroll = true;
                setTimeout(() => {
                  animation(false, props.step);
                }, props.delay);
              });
            } else {
              init();
            }
            testList.value = [];
          });
        }
        total = targetList.length;
      });

      const init = () => {
        count = 0;
        totalCount = 0;
        listCanScroll = false;
        bufferSize = 0;
        funArgs.value = [];
        vue.nextTick(() => {
          updateOffset();

          tempOffset = 0;
          singleOffset = 0;
        });
      };

      const getBufferSize = () => {
        let tempBufferSize = targetList.length - visibleCount.value;
        tempBufferSize = Math.max(1, tempBufferSize);
        tempBufferSize = Math.min(5, tempBufferSize);
        return tempBufferSize;
      };

      const add = (index, values, cb) => {
        if (!!values && values.length > 0) {
          if (index > targetList.length) {
            index = targetList.length;
          }
          if (index < 0) {
            index = 0;
          }
          const findIndexs = [];
          if (values.length === 1) {
            visibleItems.value.forEach((v, i) => {
              if (v.index === index) {
                findIndexs.push(i);
              }
            });
          }
          const datas = [];
          values.forEach((v) => {
            datas.push({
              id: uuid(),
              data: v
            });
          });

          targetList.splice(index, 0, ...datas);
          targetList.forEach((v, i) => {
            v.index = i;
          });

          const tempBufferSize = getBufferSize();

          if (listCanScroll) {
            if (index < cursorIndex) {
              cursorIndex += 1;
              if (cursorIndex > targetList.length) {
                cursorIndex = 0;
              }
            }

            if (values.length === 1 && findIndexs.length > 0) {
              findIndexs.forEach((i) => {
                visibleItems[i] = datas[0];
              });
            }
            if (tempBufferSize !== bufferSize) {
              bufferSize = tempBufferSize;
            }
          } else {
            const fun = () => {
              let hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxWH;
              if (direction.value === 'left' || direction.value === 'right') {
                hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWH;
              }

              if (hasVerticalScroll) {
                bufferSize = tempBufferSize;
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  updateOffset();

                  tempOffset = 0;
                  singleOffset = 0;

                  initWH();
                  listCanScroll = true;
                  animation(false, props.step);
                });
              } else {
                if (props.visibleCount === (undefined)) {
                  visibleCount.value = 0;
                }
                init();
              }
              testList.value = [];
            };

            if (visibleCount.value === 0 && props.visibleCount === (undefined)) {
              initVisibleCount(() => {
                fun();
              });
            } else {
              testList.value = targetList.slice(0, visibleCount.value);
              vue.nextTick(() => {
                fun();
              });
            }
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };

      const remove = (index, num = 1, cb) => {
        if (index >= 0 && index < targetList.length) {
          targetList.splice(index, num);
          if (listCanScroll) {
            testList.value = targetList.slice(0, visibleCount.value);
            vue.nextTick(() => {
              let hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxWH;
              if (direction.value === 'left' || direction.value === 'right') {
                hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWH;
              }

              if (hasVerticalScroll) {
                const tempBufferSize = getBufferSize();

                if (tempBufferSize !== bufferSize) {
                  bufferSize = tempBufferSize;
                }
                funArgs.value = initCursorIndex();
              } else {
                init();
              }
              testList.value = [];
            });
          } else {
            init();
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
        total = targetList.length;
      };


      const reset = () => {
        vue.nextTick(() => {
          testList.value = targetList.slice(0, visibleCount.value);
          vue.nextTick(() => {
            let hasVerticalScroll = realWrapperHiddenRef.value.offsetHeight > realBoxWH;
            if (direction.value === 'left' || direction.value === 'right') {
              hasVerticalScroll = realWrapperHiddenRef.value.offsetWidth > realBoxWH;
            }
            if (hasVerticalScroll) {
              if (funArgs.value[0] === 'splice') {
                updateCursorIndex();
                vue.nextTick(() => {
                  initWH();
                });
              } else {
                funArgs.value = initCursorIndex();
                vue.nextTick(() => {
                  initWH();
                });
              }
            } else {
              init();
            }
          });
        });
      };


      const update = (index, value, cb) => {
        if (index >= 0 && index < targetList.length) {
          const findIndexs = [];
          visibleItems.value.forEach((v, i) => {
            if (v.index === index) {
              findIndexs.push(i);
            }
          });
          const data = {
            id: uuid(),
            index: index,
            data: value
          };
          targetList[index] = data;
          if (findIndexs.length > 0) {
            findIndexs.forEach((i) => {
              visibleItems[i] = data;
            });
          }
        }
        if (!!cb && typeof cb === 'function') {
          cb(targetList);
        }
      };

      expose({ add, remove, update, reset });

      vue.watch(() => props.modelValue, (val) => {
        if (val) {
          animation(false, props.step);
        }
      });

      vue.onUnmounted(() => {
        cancelAnimationFrame(reqFrame);
        if (!!realWrapperRef.value) {
          realWrapperRef.value.parentElement.removeEventListener('mouseenter', onMouseenter);
          realWrapperRef.value.parentElement.removeEventListener('mouseleave', onMouseleave);
          realWrapperRef.value.parentElement.removeEventListener('wheel', onWheel);
        }
      });

      return {
        realBoxRef,
        realWrapperRef,
        visibleItems,
        offset,
        testList,
        realWrapperHiddenRef,
        transform,
      }
    }
  });

  function render(_ctx, _cache, $props, $setup, $data, $options) {
    return (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
      vue.createElementVNode("div", vue.mergeProps({
        class: "vue3-seamless-wrapper",
        ref: "realWrapperRef",
        style: { transition: `transform ${_ctx.ease}`, transform: _ctx.transform }
      }, _ctx.$attrs), [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.visibleItems, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 16 /* FULL_PROPS */),
      vue.createElementVNode("div", vue.mergeProps({
        style: {"position":"absolute !important","left":"-999999px !important"},
        ref: "realWrapperHiddenRef"
      }, _ctx.$attrs), [
        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.testList, (item) => {
          return vue.renderSlot(_ctx.$slots, "default", {
            key: item.id,
            data: item.data,
            index: item.index
          })
        }), 128 /* KEYED_FRAGMENT */))
      ], 16 /* FULL_PROPS */)
    ], 64 /* STABLE_FRAGMENT */))
  }

  var css_248z = "\n.vue3-seamless-wrapper[data-v-b156a416] {\r\n  width: 100%;\r\n  height: 100%;\n}\r\n";
  styleInject(css_248z);

  script.render = render;
  script.__scopeId = "data-v-b156a416";
  script.__file = "packages/Vue3SeamlessScroll.vue";

  const install = function (app, options = {}) {
    app.component(options.name || script.name, script);
  };

  function index (app) {
    app.use(install);
  }

  exports.HorizontalScroll = script$1;
  exports.VerticalScroll = script$2;
  exports.Vue3SeamlessScroll = script;
  exports.default = index;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
