{
  "version": 3,
  "sources": ["../src/index.ts", "../src/Constants.ts", "../src/Char.ts", "../src/Word.ts", "../src/Line.ts", "../src/Paragraph.ts", "../src/Lyric.ts"],
  "sourcesContent": ["export * from \"./Char\";\nexport * from \"./Constants\";\nexport * from \"./Line\";\nexport * from \"./Lyric\";\nexport * from \"./Paragraph\";\nexport * from \"./Word\";\n", "export const CHAR_TYPES = {\n  WHITESPACE: \"whitespace\",\n  ALPHABET: \"alphabet\",\n  NUMBER: \"number\",\n  KANJI: \"kanji\",\n  HIRAGANA: \"hiragana\",\n  KATAKANA: \"katakana\",\n  OTHER: \"other\",\n} as const;\n\nexport type CharType = (typeof CHAR_TYPES)[keyof typeof CHAR_TYPES];\n\nexport type WordTimeline = {\n  wordID: string;\n  text: string;\n  begin: number;\n  end: number;\n  hasWhitespace?: boolean;\n  hasNewLine?: boolean;\n};\n", "import { CHAR_TYPES, type CharType } from \"./Constants\";\n\nexport type CharArgs = {\n  wordID: string;\n  position: number;\n  text: string;\n  begin: number;\n  end: number;\n};\n\nexport class Char {\n  id: string;\n  wordID: string;\n  text: string;\n  type: CharType;\n  position: number;\n  begin: number;\n  end: number;\n\n  constructor(props: CharArgs) {\n    this.id = \"\";\n    this.wordID = props.wordID;\n    this.position = props.position;\n    this.text = props.text;\n    this.begin = props.begin;\n    this.end = props.end;\n    this.type = \"other\";\n\n    this.init();\n  }\n\n  private init() {\n    this.id = `char-${crypto.randomUUID()}`;\n    this.type = this.getType();\n  }\n\n  public betweenDuration(c: Char): number {\n    if (this.id === c.id) {\n      throw new Error(\"Can not compare between the same char\");\n    }\n    return c.begin > this.end ? c.begin - this.end : this.begin - c.end;\n  }\n\n  public duration(): number {\n    if (this.begin >= this.end) {\n      throw new Error(\"Can not calculate duration of a invalid char\");\n    }\n    return this.end - this.begin;\n  }\n\n  private getType(): CharType {\n    if (/^\\s+$/.test(this.text)) {\n      return CHAR_TYPES.WHITESPACE;\n    }\n    if (/^[a-zA-Z]+$/.test(this.text)) {\n      return CHAR_TYPES.ALPHABET;\n    }\n    if (/^[0-9]+$/.test(this.text)) {\n      return CHAR_TYPES.NUMBER;\n    }\n    if (/^[\\u4E00-\\u9FFF]+$/.test(this.text)) {\n      return CHAR_TYPES.KANJI;\n    }\n    if (/^[\\u3040-\\u309F]+$/.test(this.text)) {\n      return CHAR_TYPES.HIRAGANA;\n    }\n    if (/^[\\u30A0-\\u30FF]+$/.test(this.text)) {\n      return CHAR_TYPES.KATAKANA;\n    }\n    return CHAR_TYPES.OTHER;\n  }\n\n  public isCurrent(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): boolean {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return equal\n      ? this.begin <= now + offset && now + offset <= this.end\n      : this.begin < now + offset && now + offset < this.end;\n  }\n\n  public needBetweenWhitespace(c: Char): boolean {\n    if (this.id === c.id) {\n      throw new Error(\"Can not compare between the same char\");\n    }\n    if (\n      this.getType() === CHAR_TYPES.WHITESPACE ||\n      c.getType() === CHAR_TYPES.WHITESPACE\n    ) {\n      return false;\n    }\n    if (\n      [CHAR_TYPES.KANJI, CHAR_TYPES.HIRAGANA, CHAR_TYPES.KATAKANA].some(\n        (t) => t === this.getType(),\n      ) &&\n      [CHAR_TYPES.KANJI, CHAR_TYPES.HIRAGANA, CHAR_TYPES.KATAKANA].some(\n        (t) => t === c.getType(),\n      )\n    ) {\n      return false;\n    }\n    return this.type !== c.type;\n  }\n}\n\nexport default Char;\n", "import { Char } from \"./Char\";\nimport { CHAR_TYPES, type WordTimeline } from \"./Constants\";\n\nexport type WordCreateArgs = {\n  lineID: string;\n  position: number;\n  timeline: WordTimeline | Omit<WordTimeline, \"wordID\">;\n};\n\nexport type WordUpdateArgs = {\n  position: number;\n  timeline: WordTimeline;\n};\n\nexport function isWordCreateArgs(\n  args: WordCreateArgs | WordUpdateArgs,\n): args is WordCreateArgs {\n  return (args as WordCreateArgs).lineID !== undefined;\n}\n\nexport function isWordTimeline(\n  args: WordTimeline | Omit<WordTimeline, \"wordID\">,\n): args is WordTimeline {\n  return (args as WordTimeline).wordID !== undefined;\n}\n\nexport class Word {\n  id: string;\n  lineID: string;\n  charByPosition: Map<number, Char>;\n  position: number;\n  timeline: WordTimeline;\n\n  constructor(props: WordCreateArgs) {\n    this.id = \"\";\n    this.timeline = {\n      ...props.timeline,\n      wordID: \"\",\n    };\n    this.lineID = props.lineID;\n    this.position = props.position;\n    this.charByPosition = new Map();\n\n    this.init(props);\n  }\n\n  private init(props: WordCreateArgs) {\n    this.id = isWordTimeline(props.timeline)\n      ? props.timeline.wordID\n      : `word-${crypto.randomUUID()}`;\n    this.timeline = {\n      ...props.timeline,\n      hasNewLine: props.timeline.hasNewLine ?? false,\n      hasWhitespace: props.timeline.hasWhitespace ?? false,\n      wordID: this.id,\n    };\n\n    const charTexts = props.timeline.text.split(\"\");\n    const durationByChar = this.duration() / charTexts.length;\n    this.charByPosition = charTexts.reduce<Map<number, Char>>(\n      (acc, char, index) => {\n        const position = index + 1;\n        acc.set(\n          position,\n          new Char({\n            wordID: this.id,\n            position,\n            text: char,\n            begin: this.begin() + index * durationByChar,\n            end: this.begin() + position * durationByChar,\n          }),\n        );\n        return acc;\n      },\n      this.charByPosition,\n    );\n  }\n\n  public update(props: WordUpdateArgs) {\n    this.timeline = props.timeline;\n    this.position = props.position;\n    const charTexts = this.timeline.text.split(\"\");\n    const durationByChar = this.duration() / charTexts.length;\n    this.charByPosition = charTexts.reduce<Map<number, Char>>(\n      (acc, char, index) => {\n        const position = index + 1;\n        acc.set(\n          position,\n          new Char({\n            wordID: this.id,\n            position,\n            text: char,\n            begin: this.begin() + index * durationByChar,\n            end: this.begin() + position * durationByChar,\n          }),\n        );\n        return acc;\n      },\n      new Map(),\n    );\n    return this;\n  }\n\n  public betweenDuration(c: Word): number {\n    if (this.id === c.id) {\n      throw new Error(`Can not compare between the same word: ${this.id}`);\n    }\n    return c.begin() > this.end()\n      ? c.begin() - this.end()\n      : this.begin() - c.end();\n  }\n\n  public charAt(position: number): Char | undefined {\n    return this.charByPosition.get(position);\n  }\n\n  public chars() {\n    return Array.from(this.charByPosition.values());\n  }\n\n  public duration(): number {\n    if (this.begin() >= this.end()) {\n      throw new Error(\n        `Can not calculate duration of a invalid word: ${\n          this.id\n        } ${this.begin()}-${this.end()}`,\n      );\n    }\n    return this.end() - this.begin();\n  }\n\n  public speed(): number {\n    const duration = this.duration();\n    return (\n      this.chars().reduce(\n        (acc, char) =>\n          acc +\n          (char.type === CHAR_TYPES.WHITESPACE\n            ? 0\n            : char.type === CHAR_TYPES.ALPHABET ||\n                char.type === CHAR_TYPES.NUMBER\n              ? 0.5\n              : 1),\n        0,\n      ) / duration\n    );\n  }\n\n  public durationByChar(): number {\n    return this.duration() / this.charByPosition.size;\n  }\n\n  public text(): string {\n    return Array.from(this.charByPosition.values())\n      .map((char) => char.text)\n      .join(\"\");\n  }\n\n  public begin(): number {\n    return this.timeline.begin;\n  }\n\n  public end(): number {\n    return this.timeline.end;\n  }\n\n  public currentChar(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): Char | undefined {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.charByPosition.values())\n      .sort((a, b) => b.begin - a.begin)\n      .find((char) => char.isCurrent(now, { offset, equal }));\n  }\n\n  public currentChars(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): Char[] {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.charByPosition.values()).filter((char) =>\n      char.isCurrent(now, { offset, equal }),\n    );\n  }\n\n  public isCurrent(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): boolean {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return equal\n      ? this.begin() <= now + offset && now + offset <= this.end()\n      : this.begin() < now + offset && now + offset < this.end();\n  }\n}\n\nexport default Word;\n", "import type Char from \"./Char\";\nimport { CHAR_TYPES } from \"./Constants\";\nimport Word, { type WordCreateArgs, type WordUpdateArgs } from \"./Word\";\n\nexport type LineCreateArgs = {\n  position: number;\n  timelines: WordCreateArgs[\"timeline\"][];\n  jointNearWord?: boolean;\n};\n\nexport type LineUpdateArgs = {\n  position: number;\n  timelines: WordUpdateArgs[\"timeline\"][];\n  jointNearWord?: boolean;\n};\n\nexport class Line {\n  id: string;\n  wordByPosition: Map<number, Word>;\n  position: number;\n\n  constructor(props: LineCreateArgs) {\n    this.id = \"\";\n    this.position = props.position;\n    this.wordByPosition = new Map();\n\n    this.init(props);\n  }\n\n  private confirmJointNearWord(\n    timeline: WordCreateArgs[\"timeline\"],\n    nextTimeline: WordCreateArgs[\"timeline\"] | undefined,\n    lastWord: Word | undefined,\n    jointNearWord: boolean,\n  ) {\n    const isWhitespace = /^\\s+$/.test(timeline.text);\n    if (isWhitespace) {\n      return undefined;\n    }\n\n    const nextIsWhitespace = nextTimeline\n      ? /^\\s+$/.test(nextTimeline.text)\n      : false;\n    const hasWhitespace = timeline.hasWhitespace || nextIsWhitespace;\n\n    // \u8FD1\u63A5\u3057\u3066\u3044\u305F\u3089\u540C\u3058\u5358\u8A9E\u3068\u3057\u3066\u6271\u3046\n    if (jointNearWord !== false) {\n      if (\n        lastWord &&\n        lastWord.end() - timeline.begin <= 0.1 &&\n        !lastWord.timeline.hasNewLine &&\n        !lastWord.timeline.hasWhitespace\n      ) {\n        return { isJoint: true, hasWhitespace };\n      }\n    }\n    return { isJoint: false, hasWhitespace };\n  }\n\n  private init(props: LineCreateArgs) {\n    this.id = `line-${crypto.randomUUID()}`;\n\n    const timeline = props.timelines.sort((a, b) => a.begin - b.begin);\n    this.wordByPosition = timeline.reduce<Map<number, Word>>(\n      (acc, tl, index) => {\n        const nextTl = timeline[index + 1];\n        const lastWord = acc.get(acc.size);\n        const res = this.confirmJointNearWord(\n          tl,\n          nextTl,\n          lastWord,\n          props.jointNearWord === true,\n        );\n        if (!res) {\n          return acc;\n        }\n        const { isJoint, hasWhitespace } = res;\n\n        // \u8FD1\u63A5\u3057\u3066\u3044\u305F\u3089\u540C\u3058\u5358\u8A9E\u3068\u3057\u3066\u6271\u3046\n        if (lastWord && isJoint) {\n          acc.set(\n            acc.size,\n            new Word({\n              lineID: this.id,\n              position: acc.size,\n              timeline: {\n                begin: lastWord.begin(),\n                end: tl.end,\n                text: lastWord.text() + tl.text,\n                hasNewLine: tl.hasNewLine === true,\n                hasWhitespace,\n              },\n            }),\n          );\n          return acc;\n        }\n\n        acc.set(\n          acc.size + 1,\n          new Word({\n            lineID: this.id,\n            position: acc.size + 1,\n            timeline: {\n              ...tl,\n              hasWhitespace,\n            },\n          }),\n        );\n        return acc;\n      },\n      new Map(),\n    );\n  }\n\n  public update(props: LineUpdateArgs) {\n    this.position = props.position;\n\n    const timeline = props.timelines.sort((a, b) => a.begin - b.begin);\n    this.wordByPosition = timeline.reduce<Map<number, Word>>(\n      (acc, tl, index) => {\n        const nextTl = timeline[index + 1];\n        const lastWord = acc.get(acc.size);\n        const res = this.confirmJointNearWord(\n          tl,\n          nextTl,\n          lastWord,\n          props.jointNearWord === true,\n        );\n        if (!res) {\n          return acc;\n        }\n        const { isJoint, hasWhitespace } = res;\n\n        // \u8FD1\u63A5\u3057\u3066\u3044\u305F\u3089\u540C\u3058\u5358\u8A9E\u3068\u3057\u3066\u6271\u3046\n        if (lastWord && isJoint) {\n          acc.set(\n            acc.size - 1,\n            lastWord.update({\n              position: acc.size,\n              timeline: {\n                wordID: lastWord.id,\n                begin: lastWord.begin(),\n                end: tl.end,\n                text: lastWord.text() + tl.text,\n                hasNewLine: tl.hasNewLine === true,\n                hasWhitespace,\n              },\n            }),\n          );\n          return acc;\n        }\n\n        const currentWord = Array.from(this.wordByPosition.values()).find(\n          (w) => w.id === tl.wordID,\n        );\n        const position = acc.size + 1;\n        acc.set(\n          position,\n          currentWord\n            ? currentWord.update({\n                position: position,\n                timeline: {\n                  ...tl,\n                  hasNewLine: tl.hasNewLine === true,\n                  hasWhitespace,\n                },\n              })\n            : new Word({\n                lineID: this.id,\n                position: position,\n                timeline: {\n                  ...tl,\n                  hasNewLine: tl.hasNewLine === true,\n                  hasWhitespace,\n                },\n              }),\n        );\n        return acc;\n      },\n      new Map(),\n    );\n\n    return this;\n  }\n\n  public begin(): number {\n    return this.wordByPosition.get(1)?.begin() || 0;\n  }\n\n  public end(): number {\n    return this.wordByPosition.get(this.wordByPosition.size)?.end() || 0;\n  }\n\n  public betweenDuration(c: Line): number {\n    if (this.id === c.id) {\n      throw new Error(\"Can not compare between the same line\");\n    }\n    return c.begin() > this.end()\n      ? c.begin() - this.end()\n      : this.begin() - c.end();\n  }\n\n  public wordAt(position: number): Word | undefined {\n    return this.wordByPosition.get(position);\n  }\n\n  public word(wordID: string): Word | undefined {\n    for (const [, word] of this.wordByPosition) {\n      if (word.id === wordID) {\n        return word;\n      }\n    }\n  }\n\n  public words(): Word[] {\n    return Array.from(this.wordByPosition.values());\n  }\n\n  public chars(): Char[] {\n    return this.words().flatMap((word) => word.chars());\n  }\n\n  public duration(): number {\n    if (this.begin() >= this.end()) {\n      throw new Error(\"Can not calculate duration of a invalid line\");\n    }\n    return this.end() - this.begin();\n  }\n\n  public speed(): number {\n    const speeds = this.words().map((w) => w.speed());\n    speeds.sort((a, b) => a - b);\n    const half = Math.floor(speeds.length / 2);\n    return Number.parseFloat(\n      (speeds.length % 2\n        ? speeds[half]\n        : (speeds[half - 1] + speeds[half]) / 2\n      ).toFixed(2),\n    );\n  }\n\n  public text(): string {\n    return this.words()\n      .map(\n        (word) =>\n          `${word.text()}${word.timeline.hasNewLine !== true && word.timeline.hasWhitespace ? \" \" : \"\"}${\n            word.timeline.hasNewLine ? \"\\n\" : \"\"\n          }`,\n      )\n      .join(\"\");\n  }\n\n  public voids(): { begin: number; end: number; duration: number }[] {\n    const words = this.words();\n\n    return words.reduce<{ begin: number; end: number; duration: number }[]>(\n      (acc, word, index) => {\n        const isFirstWord = index === 0;\n        const isLastWord = index === words.length - 1;\n\n        if (isFirstWord && word.begin() > this.begin()) {\n          acc.push({\n            begin: this.begin(),\n            end: word.begin(),\n            duration: Number(word.begin().toFixed(2)),\n          });\n        }\n        if (isLastWord && this.end() - word.end() > 0) {\n          acc.push({\n            begin: word.end(),\n            end: this.end(),\n            duration: Number((this.end() - word.end()).toFixed(2)),\n          });\n        }\n        const prevWord = words[index - 1];\n        if (prevWord && word.begin() - prevWord.end() > 0) {\n          acc.push({\n            begin: prevWord.end(),\n            end: word.begin(),\n            duration: Number((word.begin() - prevWord.end()).toFixed(2)),\n          });\n        }\n\n        return acc;\n      },\n      [],\n    );\n  }\n\n  public firstWord() {\n    return this.wordByPosition.get(1);\n  }\n\n  public lastWord() {\n    return this.wordByPosition.get(this.wordByPosition.size);\n  }\n\n  public currentWord(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): Word | undefined {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.wordByPosition.values())\n      .sort((a, b) => b.begin() - a.begin())\n      .find((word) => word.isCurrent(now, { offset, equal }));\n  }\n\n  public currentRow(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): number | undefined {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    const currentWord = Array.from(this.wordByPosition.values())\n      .sort((a, b) => b.begin() - a.begin())\n      .find((word) => word.isCurrent(now, { offset, equal }));\n    return currentWord?.position;\n  }\n\n  public currentWords(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: false,\n    },\n  ): Word[] {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.wordByPosition.values()).filter((word) =>\n      word.isCurrent(now, { offset, equal }),\n    );\n  }\n\n  public prevWord(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: 0,\n    },\n  ): Word | undefined {\n    const offset = options.offset ?? 0;\n    return Array.from(this.wordByPosition.values())\n      .sort((a, b) => b.begin() - a.begin())\n      .find((word) => word.end() < now + offset);\n  }\n\n  public rowWords(row: number): Word[] {\n    const map = this.wordGridPositionByWordID();\n    return Array.from(map.values())\n      .filter((v) => v.row === row)\n      .map((v) => v.word);\n  }\n\n  public wordsByRow(): Map<number, Word[]> {\n    const map = this.wordGridPositionByWordID();\n    return Array.from(map.values()).reduce<Map<number, Word[]>>((acc, v) => {\n      if (!acc.has(v.row)) {\n        acc.set(v.row, []);\n      }\n      acc.get(v.row)?.push(v.word);\n      return acc;\n    }, new Map());\n  }\n\n  public wordRowPosition(wordID: string): number | undefined {\n    return this.wordGridPositionByWordID().get(wordID)?.row;\n  }\n\n  public nextWord(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: 0,\n    },\n  ): Word | undefined {\n    const offset = options.offset ?? 0;\n    return Array.from(this.wordByPosition.values())\n      .sort((a, b) => a.begin() - b.begin())\n      .find((word) => word.begin() > now + offset);\n  }\n\n  public maxRowPosition() {\n    return Math.max(\n      ...Array.from(this.wordGridPositionByWordID().values()).map((v) => v.row),\n    );\n  }\n\n  public charPositions(): Map<\n    string,\n    {\n      row: number;\n      column: number;\n      inLinePosition: number;\n    }\n  > {\n    const chars = this.chars();\n    const allWords = this.words();\n    const wordPositionMap = this.wordGridPositionByWordID();\n    const map = new Map<\n      string,\n      {\n        row: number;\n        column: number;\n        inLinePosition: number;\n      }\n    >();\n    for (const char of chars) {\n      const position = this._getCharPosition(\n        char,\n        chars,\n        allWords,\n        wordPositionMap,\n      );\n      map.set(char.id, position);\n    }\n\n    return map;\n  }\n\n  private _getCharPosition(\n    char: Char,\n    allChars: Char[],\n    allWords: Word[],\n    wordPositionMap: ReturnType<Line[\"wordGridPositionByWordID\"]>,\n  ): {\n    row: number;\n    column: number;\n    inLinePosition: number;\n  } {\n    const word = allWords.find((w) => w.id === char.wordID);\n    if (!word) {\n      throw new Error(\"word not found\");\n    }\n    const inLinePosition = allChars.findIndex((c) => c.id === char.id) + 1;\n    const wordPosition = wordPositionMap.get(word.id);\n    if (!wordPosition) {\n      throw new Error(\"wordPosition not found\");\n    }\n    const sameRowWords = allWords.filter(\n      (w) =>\n        wordPositionMap.get(w.id)?.row === wordPosition.row &&\n        w.begin() < word.begin(),\n    );\n\n    const charColumnPosition =\n      sameRowWords.reduce<number>((sum, w) => {\n        return sum + w.charByPosition.size;\n      }, 0) + char.position;\n\n    return {\n      row: wordPosition.row,\n      column: charColumnPosition,\n      inLinePosition,\n    };\n  }\n\n  public isVoid(now: number): boolean {\n    const voids = this.voids();\n    return voids.some(({ begin, end }) => now >= begin && now <= end);\n  }\n\n  public isCurrent(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): boolean {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return equal\n      ? this.begin() <= now + offset && now + offset <= this.end()\n      : this.begin() < now + offset && now + offset < this.end();\n  }\n\n  public wordGridPositionByWordID(): Map<\n    string,\n    {\n      row: number;\n      column: number;\n      word: Word;\n    }\n  > {\n    const words = this.wordByPosition;\n    const map = new Map<\n      string,\n      {\n        row: number;\n        column: number;\n        word: Word;\n      }\n    >();\n\n    let row = 1;\n    let column = 0;\n\n    for (const [position, word] of words) {\n      const prevWord = words.get(position - 1);\n      if (prevWord?.timeline.hasNewLine) {\n        row++;\n        column = 1;\n      } else {\n        column++;\n      }\n      map.set(word.id, {\n        row,\n        column,\n        word,\n      });\n    }\n\n    return map;\n  }\n\n  public textsPerSecond(): number {\n    const words = this.words();\n    const duration = this.duration();\n    return (\n      words.reduce(\n        (acc, word) =>\n          acc +\n          word\n            .chars()\n            .reduce(\n              (acc, char) =>\n                acc +\n                (char.type === CHAR_TYPES.WHITESPACE\n                  ? 0\n                  : char.type === CHAR_TYPES.ALPHABET ||\n                      char.type === CHAR_TYPES.NUMBER\n                    ? 0.5\n                    : 1),\n              0,\n            ),\n        0,\n      ) / duration\n    );\n  }\n}\n\nexport default Line;\n", "import Line, { type LineCreateArgs, type LineUpdateArgs } from \"./Line\";\nimport type { Word } from \"./Word\";\n\nexport type ParagraphCreateArgs = {\n  lyricID: string;\n  position: number;\n  timelines: LineCreateArgs[\"timelines\"][];\n  lineTokenizer?: (\n    lineArgs: LineCreateArgs,\n  ) => Promise<Map<number, LineUpdateArgs>>;\n  paragraphTokenizer?: (\n    paragraphTimeLines: ParagraphCreateArgs[\"timelines\"],\n  ) => Promise<ParagraphUpdateArgs[\"timelines\"]>;\n};\n\nexport type ParagraphUpdateArgs = {\n  position: number;\n  timelines: LineUpdateArgs[\"timelines\"][];\n};\n\nexport function isParagraphCreateArgs(\n  args: ParagraphCreateArgs | ParagraphUpdateArgs,\n): args is ParagraphCreateArgs {\n  return (args as ParagraphCreateArgs).lyricID !== undefined;\n}\n\nexport class Paragraph {\n  id: string;\n  lyricID: string;\n  lineByPosition: Map<number, Line>;\n  position: number;\n  _args: ParagraphCreateArgs;\n\n  constructor(props: ParagraphCreateArgs) {\n    this.id = \"\";\n    this.lyricID = props.lyricID;\n    this.position = props.position;\n    this.lineByPosition = new Map();\n    this._args = props;\n  }\n\n  public async init() {\n    this.id = `paragraph-${crypto.randomUUID()}`;\n    if (this._args.paragraphTokenizer) {\n      this._args.timelines = await this._args.paragraphTokenizer(\n        this._args.timelines,\n      );\n    }\n    //begin\u304C\u76F4\u524D\u306Eend\u3088\u308A\u3082\u524D\u306E\u3068\u304D\u306F\u30DE\u30FC\u30B8\u3059\u308B\n    this._args.timelines = this._args.timelines.reduce<\n      LineCreateArgs[\"timelines\"][]\n    >((acc, timelines) => {\n      const lastTimelines = acc[acc.length - 1];\n      const last = lastTimelines\n        ? lastTimelines[lastTimelines.length - 1]\n        : null;\n      const thisFirst = timelines[0];\n      if (!thisFirst) {\n        console.error(\n          \"thisFirst is undefined\",\n          this._args.timelines,\n          timelines,\n        );\n        return acc;\n      }\n      if (\n        last &&\n        (last.end > thisFirst.begin ||\n          (last.end === thisFirst.begin && last.text.length < 6))\n      ) {\n        last.end = thisFirst.end;\n        last.text += ` ${thisFirst.text}`;\n        return acc;\n      }\n      acc.push(timelines);\n      return acc;\n    }, []);\n\n    const lineCreateArgsByPosition = this._args.timelines.reduce<\n      Array<Promise<Map<number, LineCreateArgs>>>\n    >((acc, timelines, index) => {\n      const position = index + 1;\n      if (this._args.lineTokenizer) {\n        const result = this._args.lineTokenizer({ position, timelines });\n        acc.push(result);\n        return acc;\n      }\n\n      acc.push(\n        new Promise((resolve) => {\n          resolve(\n            new Map([\n              [\n                position,\n                {\n                  jointNearWord: true,\n                  position,\n                  timelines,\n                },\n              ],\n            ]),\n          );\n        }),\n      );\n      return acc;\n    }, []);\n\n    const resolved = await Promise.all(lineCreateArgsByPosition);\n\n    this.lineByPosition = resolved.reduce<Map<number, Line>>(\n      (acc, lineByPosition) => {\n        for (const [, args] of lineByPosition) {\n          const lastLine = acc.get(acc.size);\n          const position = lastLine ? lastLine.position + 1 : acc.size + 1;\n          acc.set(\n            position,\n            new Line({\n              ...args,\n              position,\n            }),\n          );\n        }\n        return acc;\n      },\n      new Map(),\n    );\n\n    return this;\n  }\n\n  public async update(props: ParagraphUpdateArgs) {\n    this.position = props.position;\n    let timelines = props.timelines;\n    if (this._args.paragraphTokenizer) {\n      timelines = await this._args.paragraphTokenizer(timelines);\n    }\n\n    const lineUpdateCreateArgsByPosition = timelines.reduce<\n      Array<Promise<Map<number, LineUpdateArgs>>>\n    >((acc, ts, index) => {\n      const position = index + 1;\n      if (this._args.lineTokenizer) {\n        acc.push(this._args.lineTokenizer({ position, timelines: ts }));\n        return acc;\n      }\n\n      acc.push(\n        new Promise((resolve) => {\n          resolve(\n            new Map([\n              [\n                position,\n                {\n                  jointNearWord: true,\n                  position,\n                  timelines: ts,\n                },\n              ],\n            ]),\n          );\n        }),\n      );\n      return acc;\n    }, []);\n\n    const resolved = await Promise.all(lineUpdateCreateArgsByPosition);\n\n    this.lineByPosition = resolved.reduce<Map<number, Line>>(\n      (acc, lineByPosition) => {\n        for (const [, args] of lineByPosition) {\n          const lastLine = acc.get(acc.size);\n          const position = lastLine ? lastLine.position + 1 : acc.size + 1;\n          const currentLine = this.lineByPosition.get(position);\n          if (!currentLine) {\n            acc.set(\n              position,\n              new Line({\n                ...args,\n                position,\n              }),\n            );\n            continue;\n          }\n          acc.set(position, currentLine.update(args));\n        }\n        return acc;\n      },\n      new Map(),\n    );\n\n    return this;\n  }\n\n  public begin(): number {\n    return this.lineByPosition.get(1)?.begin() || 0;\n  }\n\n  public end(): number {\n    return this.lineByPosition.get(this.lineByPosition.size)?.end() || 0;\n  }\n\n  public betweenDuration(c: Paragraph): number {\n    if (this.id === c.id) {\n      throw new Error(\"Can not compare between the same paragraph\");\n    }\n    return c.begin() > this.end()\n      ? c.begin() - this.end()\n      : this.begin() - c.end();\n  }\n\n  public currentLine(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): Line | undefined {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.lineByPosition.values())\n      .sort((a, b) => a.begin() - b.begin())\n      .find((line) => line.isCurrent(now, { offset, equal }));\n  }\n\n  public currentLines(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: 0,\n      equal: true,\n    },\n  ): Line[] {\n    const offset = options.offset ?? 0;\n    const equal = options.equal ?? true;\n    return Array.from(this.lineByPosition.values())\n      .sort((a, b) => a.begin() - b.begin())\n      .filter((line) => line.isCurrent(now, { offset, equal }));\n  }\n\n  public lineAt(position: number): Line | undefined {\n    return this.lineByPosition.get(position);\n  }\n\n  public words(): Word[] {\n    return Array.from(this.lineByPosition.values()).reduce<Word[]>(\n      (acc, line) => {\n        acc.push(...line.words());\n        return acc;\n      },\n      [],\n    );\n  }\n\n  public allLines(): Line[] {\n    return Array.from(this.lineByPosition.values());\n  }\n\n  public averageLineDuration(): number {\n    const durations = Array.from(this.lineByPosition.values()).map((line) =>\n      line.duration(),\n    );\n    return (\n      durations.reduce((sum, duration) => sum + duration, 0) / durations.length\n    );\n  }\n\n  public duration(): number {\n    if (this.begin() >= this.end()) {\n      throw new Error(\"Can not calculate duration of a invalid paragraph\");\n    }\n    return this.end() - this.begin();\n  }\n\n  public speed(): number {\n    const speeds = this.allLines().map((w) => w.speed());\n    speeds.sort((a, b) => a - b);\n    const half = Math.floor(speeds.length / 2);\n    return Number.parseFloat(\n      (speeds.length % 2\n        ? speeds[half]\n        : (speeds[half - 1] + speeds[half]) / 2\n      ).toFixed(2),\n    );\n  }\n\n  public voids(): { begin: number; end: number; duration: number }[] {\n    const words = this.words();\n\n    return words.reduce<{ begin: number; end: number; duration: number }[]>(\n      (acc, word, index) => {\n        const isFirstWord = index === 0;\n        const isLastWord = index === words.length - 1;\n\n        if (isFirstWord && word.begin() > this.begin()) {\n          acc.push({\n            begin: this.begin(),\n            end: word.begin(),\n            duration: Number(word.begin().toFixed(2)),\n          });\n        }\n        if (isLastWord && this.end() - word.end() > 0) {\n          acc.push({\n            begin: word.end(),\n            end: this.end(),\n            duration: Number((this.end() - word.end()).toFixed(2)),\n          });\n        }\n        const prevWord = words[index - 1];\n        if (prevWord && word.begin() - prevWord.end() > 0) {\n          acc.push({\n            begin: prevWord.end(),\n            end: word.begin(),\n            duration: Number((word.begin() - prevWord.end()).toFixed(2)),\n          });\n        }\n\n        return acc;\n      },\n      [],\n    );\n  }\n\n  public isVoid(now: number): boolean {\n    const voids = this.voids();\n    return voids.some(({ begin, end }) => now >= begin && now <= end);\n  }\n}\n\nexport default Paragraph;\n", "import type Char from \"./Char\";\nimport type { WordTimeline } from \"./Constants\";\nimport type Line from \"./Line\";\nimport {\n  Paragraph,\n  type ParagraphCreateArgs,\n  type ParagraphUpdateArgs,\n} from \"./Paragraph\";\nimport type { Word } from \"./Word\";\n\nexport type RowStatus = {\n  wordIDs: Word[\"id\"][];\n  isCurrentRow: boolean;\n  isPrevRow: boolean;\n  isNextRow: boolean;\n  chars: Char[];\n};\n\nexport type LyricCreateArgs = {\n  initID?: boolean;\n  id?: string;\n  resourceID: string;\n  duration: number;\n  timelines: ParagraphCreateArgs[\"timelines\"][];\n  lineTokenizer?: ParagraphCreateArgs[\"lineTokenizer\"];\n  paragraphTokenizer?: ParagraphCreateArgs[\"paragraphTokenizer\"];\n  offsetSec?: number;\n};\n\nexport type LyricUpdateArgs = {\n  resourceID?: string;\n  duration?: number;\n  timelines?: ParagraphUpdateArgs[\"timelines\"][];\n  offsetSec?: number;\n};\n\nexport class Lyric {\n  id: string;\n  resourceID: string;\n  paragraphByPosition: Map<number, Paragraph>;\n  duration: number;\n  offsetSec: number;\n  _args: LyricCreateArgs;\n\n  constructor(props: LyricCreateArgs) {\n    this.id = props.id\n      ? props.id\n      : props.initID\n        ? `lyric-${crypto.randomUUID()}`\n        : \"\";\n    this.resourceID = props.resourceID;\n    this.duration = Number(props.duration.toFixed(2));\n    this.paragraphByPosition = new Map();\n    this.offsetSec = props.offsetSec ?? 0;\n    this._args = props;\n  }\n\n  public async init() {\n    const paragraphByPosition = this._args.timelines.reduce<\n      Map<number, Paragraph>\n    >((acc, timelines, index) => {\n      const position = index + 1;\n      acc.set(\n        position,\n        new Paragraph({\n          lyricID: this.id,\n          position,\n          timelines,\n          lineTokenizer: this._args.lineTokenizer,\n          paragraphTokenizer: this._args.paragraphTokenizer,\n        }),\n      );\n      return acc;\n    }, new Map());\n\n    const paragraphs = await Promise.all(\n      Array.from(paragraphByPosition.values()).map((paragraph) => {\n        return paragraph.init();\n      }),\n    );\n    this.paragraphByPosition = paragraphs.reduce((acc, paragraph) => {\n      acc.set(paragraph.position, paragraph);\n      return acc;\n    }, new Map());\n\n    return this;\n  }\n\n  public async update(props: LyricUpdateArgs): Promise<Lyric> {\n    this.resourceID = props.resourceID || this.resourceID;\n    this.duration = props.duration\n      ? Number(props.duration.toFixed(2))\n      : this.duration;\n    this.offsetSec =\n      (props.offsetSec || 0) !== this.offsetSec\n        ? props.offsetSec || 0\n        : this.offsetSec;\n\n    if (props.timelines === undefined) {\n      return this;\n    }\n\n    await Promise.all(\n      Array.from(this.paragraphByPosition.values()).map(async (paragraph) => {\n        const updatedParagraph = await paragraph.update({\n          position: paragraph.position,\n          timelines: props.timelines?.[paragraph.position - 1] || [[]],\n        });\n        this.paragraphByPosition.set(paragraph.position, updatedParagraph);\n      }),\n    );\n\n    return this;\n  }\n\n  public paragraphAt(position: number): Paragraph | undefined {\n    return this.paragraphByPosition.get(position);\n  }\n\n  public words(): Word[] {\n    return Array.from(this.paragraphByPosition.values()).reduce<Word[]>(\n      (acc, paragraph) => {\n        acc.push(...paragraph.words());\n        return acc;\n      },\n      [],\n    );\n  }\n\n  public lineParagraph(line: Line) {\n    return this.paragraphs().find(\n      (paragraph) =>\n        paragraph.lineByPosition.get(line.position)?.id === line.id,\n    );\n  }\n\n  public linePositionInLyric(line: Line) {\n    return Array.from(this.lines()).findIndex((l) => l.id === line.id) + 1;\n  }\n\n  public linePositionInParagraph(line: Line) {\n    const positions = this.lineParagraph(line)?.lineByPosition;\n    if (!positions) {\n      return;\n    }\n    return (\n      Array.from(positions.values()).findIndex((l) => l.id === line.id) + 1\n    );\n  }\n\n  public paragraphs(): Paragraph[] {\n    return Array.from(this.paragraphByPosition.values()).sort(\n      (a, b) => a.begin() - b.begin(),\n    );\n  }\n\n  public lines(): Line[] {\n    return this.paragraphs()\n      .flatMap((paragraph) => Array.from(paragraph.lineByPosition.values()))\n      .sort((a, b) => a.begin() - b.begin());\n  }\n\n  public speed(): number {\n    const speeds = this.paragraphs().map((w) => w.speed());\n    speeds.sort((a, b) => a - b);\n    const half = Math.floor(speeds.length / 2);\n    return Number.parseFloat(\n      (speeds.length % 2\n        ? speeds[half]\n        : (speeds[half - 1] + speeds[half]) / 2\n      ).toFixed(2),\n    );\n  }\n\n  public currentParagraph(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: this.offsetSec,\n      equal: true,\n    },\n  ) {\n    const offset = options.offset ?? this.offsetSec;\n    const equal = options.equal ?? true;\n\n    return this.paragraphs().find((paragraph) => {\n      return equal\n        ? paragraph.begin() <= now + offset && now + offset <= paragraph.end()\n        : paragraph.begin() < now + offset && now + offset < paragraph.end();\n    });\n  }\n\n  public currentLine(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: this.offsetSec,\n      equal: true,\n    },\n  ) {\n    const offset = options.offset ?? this.offsetSec;\n    const equal = options.equal ?? true;\n    return this.currentParagraph(now, {\n      offset,\n      equal,\n    })?.currentLine(now, {\n      offset,\n      equal,\n    });\n  }\n\n  public currentWord(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: this.offsetSec,\n      equal: true,\n    },\n  ) {\n    const offset = options.offset ?? this.offsetSec;\n    const equal = options.equal ?? true;\n\n    return this.currentLine(now, {\n      offset,\n      equal,\n    })?.currentWord(now, {\n      equal,\n      offset,\n    });\n  }\n\n  public currentChar(\n    now: number,\n    options: {\n      offset?: number;\n      equal?: boolean;\n    } = {\n      offset: this.offsetSec,\n      equal: true,\n    },\n  ) {\n    const offset = options.offset ?? this.offsetSec;\n    const equal = options.equal ?? true;\n\n    return this.currentLine(now, {\n      offset,\n      equal,\n    })\n      ?.currentWord(now, {\n        equal,\n        offset,\n      })\n      ?.currentChar(now, {\n        equal,\n        offset,\n      });\n  }\n\n  public nextParagraph(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return this.paragraphs().find((p) => p.begin() > now + offset);\n  }\n\n  public nextLine(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return this.lines().find((p) => p.begin() > now + offset);\n  }\n\n  public nextWord(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return (\n      this.currentLine(now)?.nextWord(now, { offset }) ||\n      this.nextLine(now)?.firstWord()\n    );\n  }\n\n  public prevParagraph(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return this.paragraphs()\n      .reverse()\n      .find((p) => p.end() < now + offset);\n  }\n\n  public prevLine(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return this.lines()\n      .reverse()\n      .find((p) => p.end() < now + offset);\n  }\n\n  public prevWord(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ) {\n    const offset = options.offset ?? 0;\n    return (\n      this.currentLine(now)?.prevWord(now, { offset }) ||\n      this.prevLine(now)?.lastWord()\n    );\n  }\n\n  public currentRowStatusByRow(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ): Map<number, RowStatus> | null {\n    const offset = options.offset ?? 0;\n    const { currentLine, currentWord, nextLine, prevLine } =\n      this.currentSummary(now, { offset });\n    if (!currentLine) return null;\n\n    const lineID = currentLine.id;\n\n    const wordsByLineIDAndRowPosition = this.wordsByLineIDAndRowPosition();\n    const wordsByRowPosition = wordsByLineIDAndRowPosition.get(lineID);\n    if (!wordsByRowPosition) return null;\n\n    const currentWordGridPositionByWordID =\n      currentLine.wordGridPositionByWordID();\n    const currentWordGridPosition = currentWordGridPositionByWordID.get(\n      currentWord?.id ?? \"\",\n    );\n    const isPrevLine = prevLine?.id === currentLine.id;\n    const isNextLine = nextLine?.id === currentLine.id;\n    const isCurrentLine = currentLine?.id === currentLine.id;\n\n    const result = Array.from(wordsByRowPosition).reduce<\n      Map<number, RowStatus>\n    >((sum, [row, words]) => {\n      return sum.set(\n        Number(row),\n        Array.from(words).reduce<RowStatus>(\n          (acc, [_, word]) => {\n            const wordChars = word.chars();\n            const wordGridPosition = currentWordGridPositionByWordID.get(\n              word?.id ?? \"\",\n            );\n            const isCurrentRow =\n              wordGridPosition?.row === currentWordGridPosition?.row;\n\n            const isPrevRow = isPrevLine\n              ? true\n              : currentWord\n                ? word.begin() < currentWord.begin() &&\n                  (wordGridPosition?.row || 0) <\n                    (currentWordGridPosition?.row || 0)\n                : !isCurrentLine;\n\n            const isNextRow = isPrevLine\n              ? false\n              : isNextLine\n                ? Number(row) === 1\n                : currentWord\n                  ? word.begin() > currentWord.begin() &&\n                    (wordGridPosition?.row || 0) ===\n                      (currentWordGridPosition?.row || 0) + 1\n                  : true;\n\n            return {\n              wordIDs: acc.wordIDs.concat(word.id),\n              isCurrentRow,\n              isPrevRow,\n              isNextRow,\n              chars: acc.chars.concat(wordChars),\n            };\n          },\n          {\n            wordIDs: [],\n            isCurrentRow: false,\n            isPrevRow: false,\n            isNextRow: false,\n            chars: [],\n          },\n        ),\n      );\n    }, new Map());\n    return result;\n  }\n\n  public currentSummary(\n    now: number,\n    options: {\n      offset?: number;\n    } = {\n      offset: this.offsetSec,\n    },\n  ): {\n    currentChar?: Char;\n    currentLine?: Line;\n    currentParagraph?: Paragraph;\n    currentWord?: Word;\n    isConnected: boolean;\n    isParagraphFinishMotion: boolean;\n    lastLineIndex?: number;\n    lastLineIndexInParagraph?: number;\n    nextLine?: Line;\n    nextWord?: Word;\n    nextParagraph?: Paragraph;\n    nextWaitingTime?: number;\n    prevLine?: Line;\n    prevParagraph?: Paragraph;\n    prevWord?: Word;\n    lyricTextPerSecond?: number;\n    paragraphTextPerSecond?: number;\n    lineTextPerSecond?: number;\n  } {\n    const currentParagraph = this.currentParagraph(now, options);\n    const nextParagraph = this.nextParagraph(now, options);\n    const prevParagraph = this.prevParagraph(now, options);\n    const allLine = this.lines();\n    const currentLine = this.currentLine(now, options);\n    const lastLineIndexInParagraph = currentParagraph\n      ? Array.from(currentParagraph.lineByPosition.keys()).length - 1\n      : undefined;\n\n    const nextLine = this.nextLine(now, options);\n    const nextWord = this.nextWord(now, options);\n\n    const prevLine = this.prevLine(now, options);\n    const prevWord = this.prevWord(now, options);\n    const currentWord = this.currentWord(now, options);\n    const currentChar = this.currentChar(now, options);\n\n    const beforeCurrentTimeDiff =\n      currentLine && prevLine\n        ? currentLine.begin() - prevLine.end()\n        : undefined;\n    const isCurrentParagraphAverageTimeDiff = currentParagraph\n      ? currentParagraph.averageLineDuration() < 1.5\n      : undefined;\n\n    const isConnected =\n      isCurrentParagraphAverageTimeDiff === true &&\n      beforeCurrentTimeDiff !== undefined &&\n      beforeCurrentTimeDiff < 0.1;\n\n    const isParagraphFinishMotion = currentParagraph\n      ? currentParagraph && currentParagraph.end() < now\n      : true;\n\n    const nextWaitingTime = nextLine ? nextLine.begin() - now : undefined;\n\n    const lastLineIndex = allLine.length - 1;\n\n    const lyricTextPerSecond = this.speed();\n    const paragraphTextPerSecond = currentParagraph\n      ? currentParagraph.speed()\n      : undefined;\n    const lineTextPerSecond = currentLine ? currentLine.speed() : undefined;\n\n    return {\n      currentChar,\n      currentLine,\n      currentParagraph,\n      currentWord,\n      isConnected,\n      isParagraphFinishMotion,\n      lastLineIndex,\n      lastLineIndexInParagraph,\n      nextLine,\n      nextWord,\n      nextParagraph,\n      nextWaitingTime,\n      prevLine,\n      prevWord,\n      prevParagraph,\n      lyricTextPerSecond,\n      paragraphTextPerSecond,\n      lineTextPerSecond,\n    };\n  }\n\n  private _wordsByLineIDAndRowPosition(\n    acc: Map<string, Map<number, Map<number, Word>>>,\n    line: Line,\n    wordPositionMap: ReturnType<Line[\"wordGridPositionByWordID\"]>,\n  ): ReturnType<Lyric[\"wordsByLineIDAndRowPosition\"]> {\n    for (const { row, column, word } of wordPositionMap.values()) {\n      if (!acc.get(line.id)) {\n        acc.set(line.id, new Map());\n      }\n      if (!acc.get(line.id)?.get(row)) {\n        acc.get(line.id)?.set(row, new Map());\n      }\n      acc.get(line.id)?.get(row)?.set(column, word);\n    }\n\n    return acc;\n  }\n\n  /**\n   * @param reducer A reducer function to customize the result.\n   * @returns A map of words by line ID and row position.\n   */\n  public wordsByLineIDAndRowPosition(\n    reducer = this._wordsByLineIDAndRowPosition,\n  ): Map<string, Map<number, Map<number, Word>>> {\n    return this.lines().reduce((acc, line) => {\n      const wordPositionMap = line.wordGridPositionByWordID();\n\n      return reducer(acc, line, wordPositionMap);\n    }, new Map<string, Map<number, Map<number, Word>>>());\n  }\n\n  public voids(): { begin: number; end: number; duration: number }[] {\n    const words = this.words();\n\n    return words.reduce<{ begin: number; end: number; duration: number }[]>(\n      (acc, word, index) => {\n        const isFirstWord = index === 0;\n        const isLastWord = index === words.length - 1;\n\n        if (isFirstWord && word.timeline.begin > 0) {\n          acc.push({\n            begin: 0,\n            end: word.timeline.begin,\n            duration: Number(word.timeline.begin.toFixed(2)),\n          });\n        }\n        if (isLastWord && this.duration - word.timeline.end > 0) {\n          acc.push({\n            begin: word.timeline.end,\n            end: this.duration,\n            duration: Number((this.duration - word.timeline.end).toFixed(2)),\n          });\n        }\n        const prevWord = words[index - 1];\n        if (prevWord && word.timeline.begin - prevWord.timeline.end > 0) {\n          acc.push({\n            begin: prevWord.timeline.end,\n            end: word.timeline.begin,\n            duration: Number(\n              (word.timeline.begin - prevWord.timeline.end).toFixed(2),\n            ),\n          });\n        }\n\n        return acc;\n      },\n      [],\n    );\n  }\n\n  public isVoid(now: number): boolean {\n    const voids = this.voids();\n    return voids.some(({ begin, end }) => now >= begin && now <= end);\n  }\n\n  public timelines(): WordTimeline[][][] {\n    return Array.from(this.paragraphByPosition.values()).map((paragraph) => {\n      return Array.from(paragraph.lineByPosition.values()).map((line) => {\n        return Array.from(line.wordByPosition.values()).map((word) => {\n          return word.timeline;\n        });\n      });\n    });\n  }\n\n  public timelinesByLine(): WordTimeline[][] {\n    return Array.from(this.paragraphByPosition.values()).map((paragraph) => {\n      return Array.from(paragraph.lineByPosition.values()).map((line) => {\n        const firstWord = line.wordByPosition.get(1);\n        if (!firstWord) {\n          throw new Error(\"firstWord is undefined\");\n        }\n        const lastWord = line.wordByPosition.get(line.wordByPosition.size);\n        if (!lastWord) {\n          throw new Error(\"lastWord is undefined\");\n        }\n        return {\n          wordID: firstWord.id,\n          begin: firstWord.timeline.begin,\n          end: lastWord.timeline.end,\n          text: line.text(),\n          hasNewLine: lastWord.timeline.hasNewLine,\n          hasWhitespace: lastWord.timeline.hasWhitespace,\n        };\n      });\n    });\n  }\n}\n\nexport default Lyric;\n"],
  "mappings": "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",
  "names": ["index_exports", "__export", "CHAR_TYPES", "Char", "Line", "Lyric", "Paragraph", "Word", "isParagraphCreateArgs", "isWordCreateArgs", "isWordTimeline", "__toCommonJS", "CHAR_TYPES", "Char", "props", "c", "CHAR_TYPES", "now", "options", "offset", "isWordCreateArgs", "args", "isWordTimeline", "Word", "props", "charTexts", "durationByChar", "acc", "char", "index", "position", "Char", "c", "duration", "CHAR_TYPES", "now", "options", "offset", "equal", "a", "b", "Word_default", "Line", "props", "timeline", "nextTimeline", "lastWord", "jointNearWord", "nextIsWhitespace", "hasWhitespace", "a", "b", "acc", "tl", "index", "nextTl", "res", "isJoint", "Word_default", "currentWord", "w", "position", "c", "wordID", "word", "speeds", "half", "words", "isFirstWord", "isLastWord", "prevWord", "now", "options", "offset", "equal", "row", "map", "v", "chars", "allWords", "wordPositionMap", "char", "allChars", "inLinePosition", "wordPosition", "charColumnPosition", "sum", "begin", "end", "column", "duration", "CHAR_TYPES", "Line_default", "isParagraphCreateArgs", "args", "Paragraph", "props", "acc", "timelines", "lastTimelines", "last", "thisFirst", "lineCreateArgsByPosition", "index", "position", "result", "resolve", "resolved", "lineByPosition", "lastLine", "Line_default", "lineUpdateCreateArgsByPosition", "ts", "currentLine", "c", "now", "options", "offset", "equal", "a", "b", "line", "durations", "sum", "duration", "speeds", "w", "half", "words", "word", "isFirstWord", "isLastWord", "prevWord", "begin", "end", "Lyric", "props", "paragraphByPosition", "acc", "timelines", "index", "position", "Paragraph", "paragraphs", "paragraph", "updatedParagraph", "line", "l", "positions", "a", "b", "speeds", "w", "half", "now", "options", "offset", "equal", "p", "currentLine", "currentWord", "nextLine", "prevLine", "lineID", "wordsByRowPosition", "currentWordGridPositionByWordID", "currentWordGridPosition", "isPrevLine", "isNextLine", "isCurrentLine", "sum", "row", "words", "_", "word", "wordChars", "wordGridPosition", "isCurrentRow", "isPrevRow", "isNextRow", "currentParagraph", "nextParagraph", "prevParagraph", "allLine", "lastLineIndexInParagraph", "nextWord", "prevWord", "currentChar", "beforeCurrentTimeDiff", "isConnected", "isParagraphFinishMotion", "nextWaitingTime", "lastLineIndex", "lyricTextPerSecond", "paragraphTextPerSecond", "lineTextPerSecond", "wordPositionMap", "column", "reducer", "isFirstWord", "isLastWord", "begin", "end", "firstWord", "lastWord"]
}
