import { split as E, isString as S, isArray as g } from "lodash-es";
import { openBlock as o, createElementBlock as l, normalizeClass as h, toDisplayString as A, resolveComponent as y, createElementVNode as m, Fragment as T, renderList as x, createBlock as I, createVNode as v, createCommentVNode as L } from "vue";
import { at as p } from "./index-691eb34d.js";
import "axios";
import "@vueuse/core";
import "vue-i18n";
const N = (t, e) => {
  if (!Array.isArray(t) || !Array.isArray(e) || t.length !== e.length)
    return !1;
  for (let r = 0; r < t.length; r++)
    if (t[r] !== e[r])
      return !1;
  return !0;
};
function _(t) {
  return typeof t == "number" && !Number.isNaN(t) && Number.isFinite(t);
}
function $(t, e) {
  return _(t) && _(e) && t <= e;
}
const D = (t, e) => $(t, e) ? (t = Math.ceil(t), e = Math.floor(e), Math.floor(Math.random() * (e - t + 1)) + t) : -1;
function R(t, e, r) {
  if (e === r)
    return;
  const n = t[e];
  t[e] = t[r], t[r] = n;
}
const G = (t) => {
  if (Array.isArray(t))
    for (let e = t.length - 1; e > 0; e--) {
      const r = D(0, e);
      R(t, e, r);
    }
};
const b = "vue-typer-caret-", B = {
  props: {
    /**
     * Caret animation similar to Sublime and VSCode: 'solid', 'blink', 'smooth', 'phase', 'expand'.
     */
    animation: {
      type: String,
      default: "blink",
      validator: (t) => /^solid$|^blink$|^smooth$|^phase$|^expand$/.test(t)
    }
  },
  computed: {
    animationClass() {
      return b + this.animation;
    }
  }
};
function P(t, e, r, n, d, i) {
  return o(), l("span", {
    class: h(["caret custom", i.animationClass])
  }, null, 2);
}
const k = /* @__PURE__ */ p(B, [["render", P], ["__scopeId", "data-v-3f00f091"]]);
const M = {
  props: {
    val: {
      type: String,
      default: ""
    }
  },
  computed: {
    classes() {
      return {
        newline: this.val.indexOf(`
`) === 0
      };
    }
  }
};
function Y(t, e, r, n, d, i) {
  return o(), l("span", {
    class: h(["char", i.classes])
  }, A(r.val), 3);
}
const O = /* @__PURE__ */ p(M, [["render", Y], ["__scopeId", "data-v-868833ae"]]);
const s = {
  IDLE: "idle",
  TYPING: "typing",
  ERASING: "erasing",
  COMPLETE: "complete"
}, a = {
  BACKSPACE: "backspace",
  SELECT_BACK: "select-back",
  SELECT_ALL: "select-all",
  CLEAR: "clear"
}, K = {
  name: "KapixTyper",
  components: { Caret: k, Char: O },
  props: {
    /**
     * Text(s) to type.
     */
    text: {
      type: [String, Array],
      default: void 0,
      validator(t) {
        return typeof t == "string" ? t.length > 0 : t.every((e) => typeof e == "string" && e.length > 0);
      }
    },
    /**
     * Number of extra times to type 'text' after the first time.
     * 0 will type 'text' once, 1 will type twice, Infinity will type forever.
     */
    repeat: {
      type: Number,
      default: 1 / 0,
      validator: (t) => t >= 0
    },
    /**
     * Randomly shuffles 'text' (using Fisher-Yates algorithm) before typing it.
     * If 'repeat' > 0, 'text' will be shuffled again before each repetition.
     */
    shuffle: {
      type: Boolean,
      default: !1
    },
    /**
     * 'typing'  - starts KapixTyper off as a blank space and begins to type the first word.
     * 'erasing' - starts KapixTyper off with the first word already typed, and begins to erase.
     */
    initialAction: {
      type: String,
      default: s.TYPING,
      validator: (t) => !!t.match(`^${s.TYPING}|${s.ERASING}$`)
    },
    /**
     * Milliseconds to wait before typing the first character.
     */
    preTypeDelay: {
      type: Number,
      default: 70,
      validator: (t) => t >= 0
    },
    /**
     * Milliseconds to wait after typing a character, until the next character is typed.
     */
    typeDelay: {
      type: Number,
      default: 200,
      validator: (t) => t >= 0
    },
    /**
     * Milliseconds to wait before performing the first erase action (backspace, highlight, etc.).
     */
    preEraseDelay: {
      type: Number,
      default: 2e3,
      validator: (t) => t >= 0
    },
    /**
     * Milliseconds to wait after performing an erase action (backspace, highlight, etc.),
     * until the next erase action can start.
     */
    eraseDelay: {
      type: Number,
      default: 170,
      validator: (t) => t >= 0
    },
    /**
     * 'backspace'   - Erase one character at a time, like pressing backspace.
     * 'select-back' - Highlight back one character at a time; erase once all characters are highlighted.
     * 'select-all'  - Highlight all characters at once; erase afterwards.
     * 'clear'       - Immediately erases everything; text simply disappears.
     */
    eraseStyle: {
      type: String,
      default: a.BACKSPACE,
      validator: (t) => Object.keys(a).some((e) => a[e] === t)
    },
    /**
     * Flag to erase everything once KapixTyper is finished typing. Set to false to leave the last word visible.
     */
    eraseOnComplete: {
      type: Boolean,
      default: !1
    },
    /**
     * Caret animation style. See Caret.vue.
     */
    caretAnimation: {
      type: String,
      default: null
    }
  },
  emits: ["typed", "typed-char", "erased", "completed"],
  data() {
    return {
      state: s.IDLE,
      nextState: null,
      spool: [],
      spoolIndex: -1,
      previousTextIndex: -1,
      currentTextIndex: -1,
      repeatCounter: 0,
      actionTimeout: 0,
      actionInterval: 0
    };
  },
  computed: {
    caretClasses() {
      const t = this.state === s.IDLE;
      return {
        idle: t,
        "pre-type": t && this.nextState === s.TYPING,
        "pre-erase": t && this.nextState === s.ERASING,
        typing: this.state === s.TYPING,
        selecting: this.state === s.ERASING && this.isSelectionBasedEraseStyle,
        erasing: this.state === s.ERASING && !this.isSelectionBasedEraseStyle,
        complete: this.state === s.COMPLETE
      };
    },
    rightCharClasses() {
      return {
        selected: this.state === s.ERASING && this.isSelectionBasedEraseStyle,
        erased: this.state !== s.ERASING || this.state === s.ERASING && !this.isSelectionBasedEraseStyle
      };
    },
    isSelectionBasedEraseStyle() {
      return !!this.eraseStyle.match(`^${a.SELECT_BACK}|${a.SELECT_ALL}$`);
    },
    isEraseAllStyle() {
      return !!this.eraseStyle.match(`^${a.CLEAR}|${a.SELECT_ALL}$`);
    },
    isDoneTyping() {
      return this.currentTextIndex >= this.currentTextLength;
    },
    isDoneErasing() {
      return this.isSelectionBasedEraseStyle ? this.currentTextIndex <= 0 && this.previousTextIndex <= 0 : this.currentTextIndex <= 0;
    },
    onLastWord() {
      return this.spoolIndex === this.spool.length - 1;
    },
    shouldRepeat() {
      return this.repeatCounter < this.repeat;
    },
    currentText() {
      return this.spoolIndex >= 0 && this.spoolIndex < this.spool.length ? this.spool[this.spoolIndex] : "";
    },
    currentTextArray() {
      return E(this.currentText, "");
    },
    currentTextLength() {
      return this.currentTextArray.length;
    },
    numLeftChars() {
      return this.currentTextIndex < 0 ? 0 : this.currentTextIndex;
    },
    numRightChars() {
      return this.currentTextLength - this.numLeftChars;
    }
  },
  watch: {
    text(t, e) {
      t === e || N(t, e) || this.reset();
    },
    repeat() {
      this.reset();
    },
    shuffle() {
      this.reset();
    }
  },
  mounted() {
    this.init();
  },
  beforeUnmount() {
    this.cancelCurrentAction();
  },
  methods: {
    init() {
      const { text: t, initialAction: e } = this;
      if (S(t))
        this.spool = [t];
      else if (g(t)) {
        let r = t.slice();
        r = r.filter((n) => n && n.length > 0), this.spool = r;
      }
      this.repeatCounter = 0, this.resetSpool(), e === s.TYPING ? this.startTyping() : e === s.ERASING && (this.moveCaretToEnd(), this.onTyped());
    },
    reset() {
      this.cancelCurrentAction(), this.init();
    },
    resetSpool() {
      this.spoolIndex = 0, this.shuffle && this.spool.length > 1 && G(this.spool);
    },
    cancelCurrentAction() {
      this.actionInterval && (clearInterval(this.actionInterval), this.actionInterval = 0), this.actionTimeout && (clearTimeout(this.actionTimeout), this.actionTimeout = 0);
    },
    shiftCaret(t) {
      this.previousTextIndex = this.currentTextIndex;
      const e = this.currentTextIndex + t;
      this.currentTextIndex = Math.min(Math.max(e, 0), this.currentTextLength);
    },
    moveCaretToStart() {
      this.previousTextIndex = this.currentTextIndex, this.currentTextIndex = 0;
    },
    moveCaretToEnd() {
      this.previousTextIndex = this.currentTextIndex, this.currentTextIndex = this.currentTextLength;
    },
    typeStep() {
      if (!this.isDoneTyping) {
        this.shiftCaret(1);
        const t = this.previousTextIndex, e = this.currentTextArray[t];
        this.$emit("typed-char", e, t);
      }
      this.isDoneTyping && (this.cancelCurrentAction(), this.$nextTick(this.onTyped));
    },
    eraseStep() {
      this.isDoneErasing || (this.isEraseAllStyle ? this.moveCaretToStart() : this.shiftCaret(-1)), this.isDoneErasing && (this.cancelCurrentAction(), this.$nextTick(this.onErased));
    },
    startTyping() {
      this.actionTimeout || this.actionInterval || (this.moveCaretToStart(), this.state = s.IDLE, this.nextState = s.TYPING, this.actionTimeout = setTimeout(() => {
        this.state = s.TYPING, this.typeStep(), this.isDoneTyping || (this.actionInterval = setInterval(this.typeStep, this.typeDelay));
      }, this.preTypeDelay));
    },
    startErasing() {
      this.actionTimeout || this.actionInterval || (this.moveCaretToEnd(), this.state = s.IDLE, this.nextState = s.ERASING, this.actionTimeout = setTimeout(() => {
        this.state = s.ERASING, this.eraseStep(), this.isDoneErasing || (this.actionInterval = setInterval(this.eraseStep, this.eraseDelay));
      }, this.preEraseDelay));
    },
    onTyped() {
      this.$emit("typed", this.currentText), this.onLastWord ? this.eraseOnComplete || this.shouldRepeat ? this.startErasing() : this.onComplete() : this.startErasing();
    },
    onErased() {
      this.$emit("erased", this.currentText), this.onLastWord ? this.shouldRepeat ? (this.repeatCounter++, this.resetSpool(), this.startTyping()) : this.onComplete() : (this.spoolIndex++, this.startTyping());
    },
    onComplete() {
      this.state = s.COMPLETE, this.nextState = null, this.$emit("completed");
    }
  }
}, w = {
  key: 0,
  class: "vue-typer"
}, F = { class: "left" }, V = { class: "right" };
function W(t, e, r, n, d, i) {
  const f = y("Char"), C = y("Caret");
  return r.text ? (o(), l("span", w, [
    m("span", F, [
      (o(!0), l(T, null, x(i.numLeftChars, (c, u) => (o(), I(f, {
        key: u,
        class: "custom typed",
        val: i.currentTextArray[c - 1]
      }, null, 8, ["val"]))), 128))
    ]),
    v(C, {
      class: h(i.caretClasses),
      animation: r.caretAnimation
    }, null, 8, ["class", "animation"]),
    m("span", V, [
      (o(!0), l(T, null, x(i.numRightChars, (c, u) => (o(), I(f, {
        key: u,
        class: h(["custom", i.rightCharClasses]),
        val: i.currentTextArray[i.numLeftChars + c - 1]
      }, null, 8, ["val", "class"]))), 128))
    ])
  ])) : L("", !0);
}
const Q = /* @__PURE__ */ p(K, [["render", W], ["__scopeId", "data-v-56779fdd"]]);
export {
  Q as default
};
