{"version":3,"sources":["../src/core/effects/LasciiTextEffect.ts"],"names":["_LasciiTextEffect","LasciiEmitter","element","options","ResourceTracker","output","complete","i","item","from","to","start","end","char","local","intro","introPhase","last","idx","progress","error","prefersReducedMotion","endAccessibleTransition","type","context","err","toError","logLasciiError","fallbackText","text","currentPhrase","newText","oldText","length","promise","resolve","ensureLiveRegion","beginAccessibleTransition","queue","origin","cap","scrambleLen","mid","dist","maxDist","selector","elements","LasciiTextEffect","LasciiTextEffect_default"],"mappings":"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","file":"chunk-SD4LS6JE.cjs","sourcesContent":["import { type Disposable, ResourceTracker } from \"../disposable.js\";\r\nimport {\r\n  type LasciiErrorContext,\r\n  type LasciiErrorType,\r\n  logLasciiError,\r\n  toError,\r\n} from \"../errors.js\";\r\nimport { LasciiEmitter } from \"../events.js\";\r\nimport {\r\n  beginAccessibleTransition,\r\n  endAccessibleTransition,\r\n  ensureLiveRegion,\r\n  prefersReducedMotion,\r\n} from \"../a11y.js\";\r\n\r\nexport type {\r\n  LasciiCompleteDetail,\r\n  LasciiErrorDetail,\r\n  LasciiProgressDetail,\r\n  LasciiStartDetail,\r\n} from \"../events.js\";\r\nexport { LasciiEvent } from \"../events.js\";\r\n\r\nexport type RevealOriginValue = \"start\" | \"middle\";\r\n\r\nexport interface LasciiTextEffectOptions {\r\n  introChars?: string;\r\n  introPhaseFrames?: number;\r\n  chars?: string;\r\n  frameStartMax?: number;\r\n  frameEndMax?: number;\r\n  randomCharChance?: number;\r\n  phraseDelay?: number;\r\n  separator?: string;\r\n  revealOrigin?: RevealOriginValue;\r\n  reducedMotion?: boolean;\r\n}\r\n\r\nexport interface LasciiTextEffectDefaults\r\n  extends Required<Omit<LasciiTextEffectOptions, \"reducedMotion\">> {}\r\n\r\ninterface QueueItem {\r\n  from: string;\r\n  to: string;\r\n  start: number;\r\n  end: number;\r\n  char: string;\r\n}\r\n\r\nclass LasciiTextEffect extends LasciiEmitter implements Disposable {\r\n  static RevealOrigin = Object.freeze({\r\n    START: \"start\",\r\n    MIDDLE: \"middle\",\r\n  }) as Readonly<{\r\n    readonly START: \"start\";\r\n    readonly MIDDLE: \"middle\";\r\n  }>;\r\n\r\n  static DEFAULTS: LasciiTextEffectDefaults = {\r\n    introChars: \"█▓▒░x92\",\r\n    introPhaseFrames: 10,\r\n    chars: \"!<>-_\\\\/[]{}—=+*^?#________\",\r\n    frameStartMax: 40,\r\n    frameEndMax: 40,\r\n    randomCharChance: 0.28,\r\n    phraseDelay: 800,\r\n    separator: \"|:|\",\r\n    revealOrigin: LasciiTextEffect.RevealOrigin.START,\r\n  };\r\n\r\n  el: HTMLElement;\r\n  config: LasciiTextEffectDefaults;\r\n  queue: QueueItem[];\r\n  frame: number;\r\n  frameRequest: number | null;\r\n  resolve: (() => void) | null;\r\n  safetyTimeout: ReturnType<typeof setTimeout> | null;\r\n  phraseTimeout: ReturnType<typeof setTimeout> | null;\r\n  rawText: string;\r\n  phrases: string[];\r\n  shouldLoop: boolean;\r\n  counter: number;\r\n  failed: boolean;\r\n  private readonly tracker = new ResourceTracker();\r\n  private readonly reduceMotion: boolean;\r\n\r\n  constructor(element: HTMLElement, options: LasciiTextEffectOptions = {}) {\r\n    super();\r\n    this.el = element;\r\n    this.config = { ...LasciiTextEffect.DEFAULTS, ...options };\r\n    this.queue = [];\r\n    this.frame = 0;\r\n    this.frameRequest = null;\r\n    this.resolve = null;\r\n    this.safetyTimeout = null;\r\n    this.phraseTimeout = null;\r\n    this.rawText = (this.el.textContent ?? \"\").trim();\r\n    this.phrases = [];\r\n    this.shouldLoop = false;\r\n    this.counter = 0;\r\n    this.failed = false;\r\n    this.reduceMotion = prefersReducedMotion(options.reducedMotion);\r\n\r\n    this.tracker.track(() => {\r\n      this.stopActiveWork();\r\n      endAccessibleTransition(this.el);\r\n    });\r\n\r\n    try {\r\n      this.phrases = this.extractPhrases();\r\n      this.shouldLoop = this.rawText.includes(this.config.separator);\r\n      this.clearInitialText();\r\n    } catch (error) {\r\n      this.handleError(\"text_effect_initialization_failed\", error);\r\n      return;\r\n    }\r\n\r\n    queueMicrotask(() => {\r\n      if (this.failed || this.tracker.isDisposed) return;\r\n      try {\r\n        this.start();\r\n      } catch (error) {\r\n        this.handleError(\"text_effect_initialization_failed\", error);\r\n      }\r\n    });\r\n  }\r\n\r\n  get disposed(): boolean {\r\n    return this.tracker.isDisposed;\r\n  }\r\n\r\n  dispose(): void {\r\n    if (this.tracker.isDisposed) return;\r\n    this.failed = true;\r\n    this.tracker.dispose();\r\n  }\r\n\r\n  private ensureNotDisposed(): void {\r\n    if (this.tracker.isDisposed) {\r\n      throw new Error(\"LasciiTextEffect has been disposed\");\r\n    }\r\n  }\r\n\r\n  private handleError(\r\n    type: LasciiErrorType | string,\r\n    error: unknown,\r\n    context: LasciiErrorContext = {},\r\n  ): void {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n    this.failed = true;\r\n    const err = toError(error);\r\n    logLasciiError(type, err, {\r\n      element: this.el,\r\n      config: this.config,\r\n      ...context,\r\n    });\r\n    this.stopActiveWork();\r\n    this.fallbackToOriginal();\r\n    endAccessibleTransition(this.el);\r\n    this.emit(\"error\", { error: err });\r\n  }\r\n\r\n  private stopActiveWork(): void {\r\n    if (this.frameRequest !== null) {\r\n      cancelAnimationFrame(this.frameRequest);\r\n      this.frameRequest = null;\r\n    }\r\n    if (this.safetyTimeout !== null) {\r\n      clearTimeout(this.safetyTimeout);\r\n      this.safetyTimeout = null;\r\n    }\r\n    if (this.phraseTimeout !== null) {\r\n      clearTimeout(this.phraseTimeout);\r\n      this.phraseTimeout = null;\r\n    }\r\n    this.resolve?.();\r\n    this.resolve = null;\r\n  }\r\n\r\n  private fallbackToOriginal(): void {\r\n    const fallbackText = this.phrases[0] ?? this.rawText;\r\n    this.el.textContent = fallbackText;\r\n  }\r\n\r\n  extractPhrases(): string[] {\r\n    return this.rawText\r\n      .split(this.config.separator)\r\n      .map((text) => text.trim())\r\n      .filter(Boolean);\r\n  }\r\n\r\n  clearInitialText(): void {\r\n    this.el.textContent = \"\";\r\n  }\r\n\r\n  start(): void {\r\n    this.ensureNotDisposed();\r\n    if (this.failed || !this.phrases.length) return;\r\n    if (this.shouldLoop) {\r\n      this.displayNextPhrase();\r\n    } else {\r\n      this.setText(this.phrases[0]);\r\n    }\r\n  }\r\n\r\n  displayNextPhrase(): void {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n    const currentPhrase = this.phrases[this.counter];\r\n    this.setText(currentPhrase).then(() => {\r\n      if (this.failed || this.tracker.isDisposed) return;\r\n      this.phraseTimeout = setTimeout(() => {\r\n        this.phraseTimeout = null;\r\n        if (this.failed || this.tracker.isDisposed) return;\r\n        this.updateCounter();\r\n        this.displayNextPhrase();\r\n      }, this.config.phraseDelay);\r\n    });\r\n  }\r\n\r\n  updateCounter(): void {\r\n    this.counter = (this.counter + 1) % this.phrases.length;\r\n  }\r\n\r\n  setText(newText: string): Promise<void> {\r\n    this.ensureNotDisposed();\r\n    if (this.failed) {\r\n      return Promise.resolve();\r\n    }\r\n\r\n    try {\r\n      const oldText = this.el.innerText;\r\n      const length = Math.max(oldText.length, newText.length);\r\n      const promise = new Promise<void>((resolve) => {\r\n        this.resolve = resolve;\r\n      });\r\n      this.queue = this.buildQueue(oldText, newText, length);\r\n      ensureLiveRegion(this.el);\r\n      this.emit(\"start\", { text: newText });\r\n      this.emit(\"progress\", { progress: 0 });\r\n      if (this.reduceMotion) {\r\n        this.completeAnimation(newText);\r\n        return Promise.resolve();\r\n      }\r\n      beginAccessibleTransition(this.el, newText);\r\n      this.resetAnimation();\r\n\r\n      this.safetyTimeout = setTimeout(() => {\r\n        this.safetyTimeout = null;\r\n        if (this.frameRequest) {\r\n          cancelAnimationFrame(this.frameRequest);\r\n          this.frameRequest = null;\r\n          this.completeAnimation(newText);\r\n        }\r\n      }, 3000);\r\n\r\n      return promise;\r\n    } catch (error) {\r\n      this.handleError(\"text_effect_animation_failed\", error, { newText });\r\n      return Promise.resolve();\r\n    }\r\n  }\r\n\r\n  buildQueue(oldText: string, newText: string, length: number): QueueItem[] {\r\n    const queue: QueueItem[] = [];\r\n    const origin =\r\n      this.config.revealOrigin ?? LasciiTextEffect.RevealOrigin.START;\r\n    const cap = this.config.frameStartMax;\r\n    const scrambleLen = Math.max(\r\n      1,\r\n      Math.floor(Math.random() * this.config.frameEndMax),\r\n    );\r\n\r\n    for (let i = 0; i < length; i++) {\r\n      const from = oldText[i] || \"\";\r\n      const to = newText[i] || \"\";\r\n      let start = 0;\r\n\r\n      if (origin === LasciiTextEffect.RevealOrigin.MIDDLE) {\r\n        const mid = (length - 1) / 2;\r\n        const dist = Math.abs(i - mid);\r\n        const maxDist = Math.max(mid, length - 1 - mid) || 1;\r\n        start = Math.floor((dist / maxDist) * cap);\r\n      } else if (length > 1) {\r\n        start = Math.floor((i / (length - 1)) * cap);\r\n      }\r\n\r\n      const end = start + scrambleLen;\r\n      queue.push({ from, to, start, end, char: \"\" });\r\n    }\r\n    return queue;\r\n  }\r\n\r\n  resetAnimation(): void {\r\n    if (this.frameRequest !== null) {\r\n      cancelAnimationFrame(this.frameRequest);\r\n      this.frameRequest = null;\r\n    }\r\n    this.frame = 0;\r\n    this.update();\r\n  }\r\n\r\n  update = (): void => {\r\n    if (this.failed || this.tracker.isDisposed) return;\r\n\r\n    try {\r\n      let output = \"\";\r\n      let complete = 0;\r\n      for (let i = 0; i < this.queue.length; i++) {\r\n        const item = this.queue[i];\r\n        const { from, to, start, end } = item;\r\n        let char = item.char;\r\n        if (this.frame >= end) {\r\n          complete++;\r\n          output += to;\r\n        } else if (this.frame >= start) {\r\n          const local = this.frame - start;\r\n          const intro = this.config.introChars ?? \"\";\r\n          const introPhase = this.config.introPhaseFrames ?? 10;\r\n          if (intro.length && local < introPhase) {\r\n            const last = intro.length - 1;\r\n            const idx =\r\n              last <= 0\r\n                ? 0\r\n                : Math.min(\r\n                    last,\r\n                    Math.floor((local / Math.max(introPhase - 1, 1)) * last),\r\n                  );\r\n            char = intro[idx];\r\n            this.queue[i].char = char;\r\n          } else if (!char || Math.random() < this.config.randomCharChance) {\r\n            char = this.randomChar();\r\n            this.queue[i].char = char;\r\n          }\r\n          output += `<span class=\"dud\">${char}</span>`;\r\n        } else {\r\n          output += from;\r\n        }\r\n      }\r\n      this.el.innerHTML = output;\r\n      const progress =\r\n        this.queue.length === 0 ? 1 : complete / this.queue.length;\r\n      this.emit(\"progress\", { progress });\r\n      if (complete === this.queue.length) {\r\n        this.completeAnimation(this.queue.map((item) => item.to).join(\"\"));\r\n      } else {\r\n        this.frameRequest = requestAnimationFrame(this.update);\r\n        this.frame++;\r\n      }\r\n    } catch (error) {\r\n      this.handleError(\"text_effect_animation_failed\", error);\r\n    }\r\n  };\r\n\r\n  randomChar(): string {\r\n    return this.config.chars[\r\n      Math.floor(Math.random() * this.config.chars.length)\r\n    ];\r\n  }\r\n\r\n  private completeAnimation(text: string): void {\r\n    if (this.failed || this.tracker.isDisposed) {\r\n      this.resolve?.();\r\n      this.resolve = null;\r\n      return;\r\n    }\r\n    this.el.textContent = text;\r\n    endAccessibleTransition(this.el);\r\n    if (this.safetyTimeout !== null) {\r\n      clearTimeout(this.safetyTimeout);\r\n      this.safetyTimeout = null;\r\n    }\r\n    this.emit(\"progress\", { progress: 1 });\r\n    this.emit(\"complete\", { text });\r\n    this.resolve?.();\r\n    this.resolve = null;\r\n  }\r\n\r\n  static init(selector = \"[data-lascii-text]\"): LasciiTextEffect[] {\r\n    const elements = document.querySelectorAll(selector);\r\n    return Array.from(\r\n      elements,\r\n      (element) => new LasciiTextEffect(element as HTMLElement),\r\n    );\r\n  }\r\n}\r\n\r\nexport default LasciiTextEffect;\r\n"]}