anipar
Version:
Anime title Parser built for AnimeGarden.
1 lines • 56.7 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/context.ts","../src/tokenizer.ts","../src/episodes.ts","../src/keyword.ts","../src/title.ts","../src/parser.ts"],"sourcesContent":["import type { ParseOptions, ParseResult } from './types';\n\nimport { Token } from './tokenizer';\n\nexport class Context {\n // Left cursor for consumed tokens\n public left = 0;\n\n // Right cursor for consumed tokens\n public right;\n\n public tokens: Token[];\n\n public options: ParseOptions;\n\n public result: Partial<ParseResult>;\n\n public tags: string[];\n\n public constructor(tokens: Token[], options: ParseOptions) {\n this.tokens = tokens;\n this.options = options;\n this.right = tokens.length - 1;\n this.tags = [];\n this.result = {};\n }\n\n public update<K1 extends keyof ParseResult>(key: K1, value: ParseResult[K1]) {\n this.result[key] = value;\n }\n\n public update2<\n K1 extends keyof Required<ParseResult>,\n K2 extends keyof Required<ParseResult>[K1]\n >(key1: K1, key2: K2, value: Required<ParseResult>[K1][K2]) {\n if (!this.result[key1]) {\n // @ts-expect-error\n this.result[key1] = {};\n }\n // @ts-expect-error\n this.result[key1][key2] = value;\n }\n\n public update3<\n K1 extends keyof Required<ParseResult>,\n K2 extends keyof Required<ParseResult>[K1],\n K3 extends keyof Required<Required<ParseResult>[K1]>[K2]\n >(key1: K1, key2: K2, key3: K3, value: Required<Required<ParseResult>[K1]>[K2][K3]) {\n if (!this.result[key1]) {\n // @ts-expect-error\n this.result[key1] = {};\n }\n // @ts-expect-error\n if (!this.result[key1][key2]) {\n // @ts-expect-error\n this.result[key1][key2] = {};\n }\n // @ts-expect-error\n this.result[key1][key2][key3] = value;\n }\n\n public get hasEpisode() {\n return this.result.episode || this.result.episodes || this.result.episodeRange;\n }\n\n public validate(): ParseResult | undefined {\n this.result.tags = this.tags;\n return this.result as ParseResult;\n }\n}\n","export class Token {\n public readonly text: string;\n\n public readonly left: string | undefined;\n\n public readonly right: string | undefined;\n\n public constructor(text: string, left?: string, right?: string) {\n this.text = text;\n this.left = left;\n this.right = right;\n }\n\n public get isWrapped() {\n return this.left && this.right;\n }\n\n public slice(start: number, end?: number) {\n const text = this.text.slice(start, end);\n return new Token(text, this.left, this.right);\n }\n\n public trim() {\n const text = this.text.trim();\n return new Token(text, this.left, this.right);\n }\n\n public toString() {\n return `${this.left ?? ''}${this.text}${this.right ?? ''}`;\n }\n}\n\nexport const Wrappers = new Map([\n ['[', ']'],\n ['【', '】'],\n ['(', ')'],\n ['(', ')'],\n ['{', '}']\n]);\n\nexport const RevWrappers = new Map([...Wrappers.entries()].map(([k, v]) => [v, k]));\n\nexport function tokenize(text: string) {\n const tokens: Token[] = [];\n\n let cursor = 0;\n let cur = '';\n let left: string | undefined = undefined;\n let right: string | undefined = undefined;\n while (cursor < text.length) {\n const char = text[cursor];\n if (Wrappers.has(char)) {\n if (!left) {\n if (cur) {\n tokens.push(new Token(cur.trim()));\n cur = '';\n }\n left = char;\n right = Wrappers.get(char)!;\n } else {\n // nest wrapper\n cur += char;\n }\n } else if (left && right && char === right) {\n tokens.push(new Token(cur.trim(), left, right));\n cur = '';\n left = undefined;\n right = undefined;\n } else {\n cur += char;\n }\n cursor += 1;\n }\n if (cur) {\n tokens.push(new Token(cur.trim()));\n }\n\n return tokens.filter((t) => t.text);\n}\n","import { Context } from './context';\n\nconst WrappedEpisodeRE = /^(?<ep1>\\d+)(?:\\.(\\d))?(?:[vV](\\d+))?$|^第(?<ep2>\\d+)[集话話]$/;\nconst WrappedMovieRE = /^Movie [vV](\\d+)$/;\n\nconst EpisodesRange1 = /^(\\d+)-(\\d+)(?:\\s*.*)$/;\nconst EpisodesRange2 = /^全(\\d+)集$/;\n\nexport function parseWrappedEpisodes(ctx: Context) {\n const token = ctx.tokens[ctx.right];\n const text = token.text;\n if (token.isWrapped && matchEpiodes(ctx, text)) {\n ctx.right -= 1;\n return true;\n }\n return false;\n}\n\nexport function matchEpiodes(ctx: Context, text: string) {\n // 1. Single episode\n {\n const res = WrappedEpisodeRE.exec(text);\n if (res) {\n const epText = res.groups?.ep1! || res.groups?.ep2!;\n const ep = +epText;\n if (!Number.isNaN(ep)) {\n // Handle year: [2024]\n if (1949 <= ep && ep <= 2099 && text === epText && ctx.hasEpisode) {\n ctx.update('year', ep);\n return true;\n }\n\n ctx.update2('episode', 'number', ep);\n // 1.5\n if (res[2] && !Number.isNaN(res[2])) {\n ctx.update2('episode', 'numberSub', +res[2]);\n }\n // 3v2\n if (res[3] && !Number.isNaN(res[3])) {\n ctx.update('version', +res[3]);\n }\n return true;\n }\n }\n }\n {\n // [Movie] / [Movie v2]\n const res = WrappedMovieRE.exec(text);\n if (res) {\n if (res[1] && !Number.isNaN(res[1])) {\n ctx.update('version', +res[1]);\n }\n ctx.update('type', 'Movie');\n return true;\n }\n }\n\n // 2. Episode range\n {\n // 01-26\n const res = EpisodesRange1.exec(text);\n if (res) {\n const from = +res[1];\n const to = +res[2];\n if (!Number.isNaN(from) && !Number.isNaN(to)) {\n ctx.update2('episodeRange', 'from', from);\n ctx.update2('episodeRange', 'to', to);\n return true;\n }\n }\n }\n {\n // 全26集\n const res = EpisodesRange2.exec(text);\n if (res) {\n const to = +res[1];\n if (!Number.isNaN(to)) {\n ctx.update2('episodeRange', 'from', 1);\n ctx.update2('episodeRange', 'to', to);\n return true;\n }\n }\n }\n\n return false;\n}\n\nconst SuffixEpisodeRE = [/- (\\d+)(?:\\.(\\d))?$/, /第(\\d+)(?:\\.(\\d))?[集话話]$/];\n\nexport function parseSuffixEpisodes(ctx: Context) {\n if (ctx.result.episode || ctx.result.episodes || ctx.result.episodeRange) {\n return true;\n }\n\n const token = ctx.tokens[ctx.right];\n const text = token.text;\n for (const RE of SuffixEpisodeRE) {\n const res = RE.exec(text);\n if (res) {\n const ep = +res[1];\n if (!Number.isNaN(ep)) {\n ctx.update2('episode', 'number', ep);\n\n // 1.5\n if (res[2] && !Number.isNaN(res[2])) {\n ctx.update2('episode', 'numberSub', +res[2]);\n }\n\n // Remove token suffix\n ctx.tokens[ctx.right] = token.slice(0, text.length - res[0].length).trim();\n\n return true;\n }\n }\n }\n}\n\n// Season regexp\nexport const SuffixSeasonOrEpisodesRes: Array<\n [RegExp, (res: RegExpExecArray, ctx: Context) => boolean]\n> = [\n [\n /(?:S|Season\\s?)(\\d+)$/,\n (res, ctx) => {\n const season = +res[1];\n if (!Number.isNaN(season)) {\n if (!ctx.result.season?.number || ctx.result.season.number === season) {\n ctx.update2('season', 'number', season);\n return true;\n }\n }\n return false;\n }\n ],\n [\n /(1st|2nd|3rd|[456789]th) Season$/,\n (res, ctx) => {\n const season = Number.parseInt(res[1]);\n if (!Number.isNaN(season)) {\n if (!ctx.result.season?.number || ctx.result.season.number === season) {\n ctx.update2('season', 'number', season);\n return true;\n }\n }\n return false;\n }\n ],\n [\n /第?(\\d+)[季期]$/,\n (res, ctx) => {\n const season = +res[1];\n if (!Number.isNaN(season)) {\n if (!ctx.result.season?.number || ctx.result.season.number === season) {\n ctx.update2('season', 'number', season);\n return true;\n }\n }\n return false;\n }\n ],\n [\n /第?((?:[零一二三四五六七八九]十)?[零一二三四五六七八九])[季期]$/,\n (res, ctx) => {\n const text = res[1];\n const map = {\n 零: 0,\n 一: 1,\n 二: 2,\n 三: 3,\n 四: 4,\n 五: 5,\n 六: 6,\n 七: 7,\n 八: 8,\n 九: 9\n };\n const base =\n text.length === 2 && text[0] === '十'\n ? 1\n : text.length === 3\n ? map[text[0] as keyof typeof map]!\n : 0;\n const offset = map[text[text.length - 1] as keyof typeof map];\n const season = base * 10 + offset;\n if (!ctx.result.season?.number || ctx.result.season.number === season) {\n ctx.update2('season', 'number', season);\n return true;\n }\n return false;\n }\n ],\n [\n / (\\d+)$/,\n (res, ctx) => {\n const season = +res[1];\n if (\n !Number.isNaN(season) &&\n (ctx.result.episode || ctx.result.episodes || ctx.result.episodeRange)\n ) {\n // Skip: Part 2\n if (/Parts? \\d+$/.test(res.input)) {\n return false;\n }\n if (!ctx.result.season?.number || ctx.result.season.number === season) {\n ctx.update2('season', 'number', season);\n return true;\n }\n }\n return false;\n }\n ],\n [\n /(?<ep1>\\d+)(?:\\.(\\d))?(?:[vV](\\d+))?$|^第(?<ep2>\\d+)[集话話]$/,\n (res, ctx) => {\n const ep = +(res.groups?.ep1! || res.groups?.ep2!);\n if (!Number.isNaN(ep)) {\n // Skip: Part 2\n if (/Parts? \\d+$/.test(res.input)) {\n return false;\n }\n\n ctx.update2('episode', 'number', ep);\n // 1.5\n if (res[2] && !Number.isNaN(res[2])) {\n ctx.update2('episode', 'numberSub', +res[2]);\n }\n // 3v2\n if (res[3] && !Number.isNaN(res[3])) {\n ctx.update('version', +res[3]);\n }\n return true;\n }\n return false;\n }\n ],\n [\n /(日配版)$/,\n (res, ctx) => {\n ctx.update('language', res[0]);\n return true;\n }\n ],\n [\n /(重播)$/,\n (res, ctx) => {\n ctx.tags.push(res[0]);\n return true;\n }\n ]\n];\n","import { Context } from './context';\nimport { RevWrappers, Token } from './tokenizer';\nimport { matchEpiodes, SuffixSeasonOrEpisodesRes } from './episodes';\n\nconst AudioTerm = new Set([\n // Audio channels\n '2.0CH',\n '2CH',\n '5.1',\n '5.1CH',\n 'DTS',\n 'DTS-ES',\n 'DTS5.1',\n 'TRUEHD5.1',\n // Audio codec\n 'AAC',\n 'AACX2',\n 'AAC×2',\n 'AACX3',\n 'AAC×3',\n 'AACX4',\n 'AAC×4',\n 'AC3',\n 'EAC3',\n 'E-AC-3',\n 'FLAC',\n 'FLACX2',\n 'FLAC×2',\n 'FLACX3',\n 'FLAC×3',\n 'FLACX4',\n 'FLAC×4',\n 'LOSSLESS',\n 'MP3',\n 'WAV',\n 'OGG',\n 'VORBIS',\n // Audio language\n 'DUALAUDIO',\n 'DUAL AUDIO'\n]);\n\nconst VideoTerm = new Set([\n // Frame rate\n '23.976FPS',\n '24FPS',\n '29.97FPS',\n '30FPS',\n '60FPS',\n '120FPS',\n // Video codec\n '8BIT',\n '8-BIT',\n '10BIT',\n '10BITS',\n '10-BIT',\n '10-BITS',\n 'HI10',\n 'HI10P',\n 'HI444',\n 'HI444P',\n 'HI444PP',\n 'H264',\n 'H265',\n 'H.264',\n 'H.265',\n 'X264',\n 'X265',\n 'X.264',\n 'AVC',\n 'HEVC',\n 'HEVC2',\n 'HEVC-10BIT',\n 'HEVC_OPUS',\n 'DIVX',\n 'DIVX5',\n 'DIVX6',\n 'XVID',\n // Video format\n 'AVI',\n 'RMVB',\n 'WMV',\n 'WMV3',\n 'WMV9',\n // Video quality\n 'HDR',\n 'HQ',\n 'LQ',\n // Video resolution\n 'HD',\n 'SD'\n]);\n\nconst VideoResolution = new Set([\n '480P',\n '720P',\n '1080P',\n '2160P',\n 'AI2160p',\n '1280X720',\n '1280×720',\n '1920X816',\n '1920×816',\n '1920X1080',\n '1920×1080',\n '2K',\n '4K'\n]);\n\nconst Source = new Set([\n 'BD',\n 'BDRIP',\n 'BLURAY',\n 'BLU-RAY',\n 'BDREMUX',\n 'UHDBDRIP',\n 'DVD',\n 'DVD5',\n 'DVD9',\n 'DVD-R2J',\n 'DVDRIP',\n 'DVD-RIP',\n 'R2DVD',\n 'R2J',\n 'R2JDVD',\n 'R2JDVDRIP',\n 'HDTV',\n 'HDTVRIP',\n 'TVRIP',\n 'TV-RIP',\n 'WEB',\n 'WEBCAST',\n 'WEBDL',\n 'WEB-DL',\n 'WEBRIP',\n 'WEB-RIP',\n 'WEB-MKV'\n]);\n\nconst Platfrom = new Set(['Baha', 'Bilibili', 'B-Global', 'ABEMA', 'CR', 'ViuTV', 'AMZN', 'ADN']);\n\nconst Type = new Set([\n 'GEKIJOUBAN',\n 'MOVIE',\n 'OAD',\n 'OAV',\n 'ONA',\n 'OVA',\n 'SPECIAL',\n 'SPECIALS',\n 'TV',\n '特别篇',\n '特別篇',\n '特別編',\n '特别话',\n '特別话',\n '特別話',\n '番外篇',\n '番外編',\n '剧场版',\n '劇場版',\n //\n 'SP',\n //\n 'ED',\n 'ENDING',\n 'NCED',\n 'NCOP',\n 'OP',\n 'OPENING',\n 'PREVIEW',\n 'PV'\n]);\n\nconst Languages = new Set([\n 'CN',\n 'CHS',\n 'CHT',\n 'YUE',\n 'JP',\n '简体',\n '国语中字',\n '繁體',\n '中日双语',\n '简日双语',\n '繁日雙語',\n 'HOY粵語'\n]);\n\nconst Subtitles = new Set([\n 'ASS',\n 'GB',\n 'BIG5',\n 'DUB',\n 'DUBBED',\n 'HARDSUB',\n 'HARDSUBS',\n 'RAW',\n 'SOFTSUB',\n 'SOFTSUBS',\n 'SUB',\n 'SUBBED',\n 'SUBTITLED',\n 'SRT'\n]);\n\nconst LanguagePrefixes = [\n '简体',\n '繁體',\n '简日',\n '繁日',\n '简繁日双语',\n '简繁日',\n '简繁',\n '繁简日',\n '简繁日语',\n '简日双语'\n];\n\nconst SubtitlesSufixes = new Set(['内嵌', '內嵌', '内封', '内封字幕', '外挂', '外掛']);\n\nconst PlatformLanguage = new Map([['ViuTV粵語', ['ViuTV', '粵語']]]);\n\nconst LanguageSubtitles = new Map([\n ['简体字幕', ['简体', undefined]],\n ['繁體字幕', ['繁體', undefined]],\n ['简日双语字幕', ['简日双语', undefined]],\n ['TVB粵語', ['粵語', undefined]],\n ['代理商粵語', ['粵語', undefined]],\n ['粵日雙語+內封繁體中文字幕', ['繁體中文', '內封字幕']],\n ['粵語+無對白字幕', [undefined, '無對白字幕']]\n]);\n\nconst Extension = new Set([\n '3GP',\n 'AVI',\n 'DIVX',\n 'FLV',\n 'M2TS',\n 'MKV',\n 'MOV',\n 'MP4',\n 'MPG',\n 'OGM',\n 'RM',\n 'RMVB',\n 'TS',\n 'WEBM',\n 'WMV'\n]);\n\nconst Tags = new Set(['国漫', '先行版', '先行版本', '正式版', '正式版本', 'Ani-One']);\n\n// Prefix\nconst SearchPrefix = ['检索:', '检索用:'];\nconst HiringPrefix = ['招募', '字幕社招人'];\nconst OtherPrefix = ['▶'];\n\nfunction matchSingleTag(ctx: Context, text: string) {\n const upper = text.toUpperCase();\n // Match keywords\n if (AudioTerm.has(upper)) {\n ctx.update3('file', 'audio', 'term', text);\n return true;\n }\n if (VideoTerm.has(upper)) {\n ctx.update3('file', 'video', 'term', text);\n return true;\n }\n if (VideoResolution.has(upper)) {\n ctx.update3('file', 'video', 'resolution', text);\n return true;\n }\n if (Source.has(upper)) {\n ctx.update('source', text);\n return true;\n }\n if (Platfrom.has(text)) {\n ctx.update('platform', text);\n return true;\n }\n if (Type.has(upper)) {\n ctx.update('type', text);\n return true;\n }\n if (Extension.has(upper)) {\n ctx.update2('file', 'extension', text);\n return true;\n }\n if (Tags.has(text)) {\n ctx.tags.push(text);\n return true;\n }\n\n // Match language and subtitles\n {\n if (Languages.has(upper)) {\n ctx.update('language', text);\n return true;\n }\n if (Subtitles.has(upper)) {\n ctx.update('subtitles', text);\n return true;\n }\n // Combine language and subtitles\n const combined = LanguageSubtitles.get(text);\n if (combined) {\n ctx.update('language', combined[0]);\n ctx.update('subtitles', combined[1]);\n return true;\n }\n const combined2 = PlatformLanguage.get(text);\n if (combined2) {\n ctx.update('platform', combined2[0]);\n ctx.update('language', combined2[1]);\n return true;\n }\n\n // Auto combined\n for (const prefix of LanguagePrefixes) {\n if (text.startsWith(prefix)) {\n const language = prefix;\n const subtitles = text.slice(prefix.length);\n if (SubtitlesSufixes.has(subtitles)) {\n ctx.update('language', language);\n ctx.update('subtitles', subtitles);\n return true;\n }\n }\n }\n }\n\n // Match regex\n {\n {\n // 2024年10月番\n const match = /^(\\d\\d\\d\\d)年(\\d\\d?)月新?番$/.exec(text);\n if (match) {\n const year = +match[1];\n const month = +match[2];\n if (1949 <= year && year <= 2099) {\n ctx.update('year', year);\n }\n if (1 <= month && month <= 12) {\n ctx.update('month', month);\n }\n return true;\n }\n }\n {\n // ★10月新番\n const match = /^★?(\\d\\d?)月新?番★?$/.exec(text);\n if (match) {\n const month = +match[1];\n if (1 <= month && month <= 12) {\n ctx.update('month', month);\n }\n return true;\n }\n }\n {\n // [2024.12.15]\n const match = /^(\\d\\d\\d\\d)\\.(\\d?\\d)\\.(\\d?\\d)$/.exec(text);\n if (match) {\n const year = +match[1];\n const month = +match[2];\n if (1949 <= year && year <= 2099) {\n ctx.update('year', year);\n }\n if (1 <= month && month <= 12) {\n ctx.update('month', month);\n }\n return true;\n }\n }\n {\n // [2024SP]\n const match = /^(\\d\\d\\d\\d)(SP)$/.exec(text);\n if (match) {\n const year = +match[1];\n const type = match[2];\n if (1949 <= year && year <= 2099) {\n ctx.update('year', year);\n }\n ctx.update('type', type);\n return true;\n }\n }\n {\n // v2\n const match = /^[vV](\\d+)$/.exec(text);\n if (match) {\n const version = +match[1];\n ctx.update('version', version);\n return true;\n }\n }\n }\n\n // Match prefix\n {\n for (const prefix of SearchPrefix) {\n if (text.startsWith(prefix)) {\n const title = text.slice(prefix.length).trim();\n ctx.tags.push(title);\n return true;\n }\n }\n for (const prefix of HiringPrefix) {\n if (text.startsWith(prefix)) {\n return true;\n }\n }\n for (const prefix of OtherPrefix) {\n if (text.startsWith(prefix)) {\n ctx.tags.push(text);\n return true;\n }\n }\n }\n\n return false;\n}\n\nconst TagSeperators = [' ', '_'];\nfunction matchMultipleTags(ctx: Context, text: string) {\n for (const sep of TagSeperators) {\n const parts = text.split(sep);\n if (parts.length <= 1) continue;\n let matched = true;\n for (let i = 0; i < parts.length; i += 1) {\n const part = parts[i];\n if (!matchSingleTag(ctx, part)) {\n matched = false;\n }\n }\n if (matched) {\n return true;\n }\n }\n return false;\n}\n\nfunction parseTag(ctx: Context, cursor: number) {\n const token = ctx.tokens[cursor];\n if (token.isWrapped) {\n const text = token.text;\n if (matchSingleTag(ctx, text)) {\n return true;\n }\n if (matchEpiodes(ctx, text)) {\n return true;\n }\n if (matchMultipleTags(ctx, text)) {\n return true;\n }\n }\n return false;\n}\n\nexport function parseRightTags(ctx: Context) {\n while (ctx.left < ctx.right) {\n if (parseTag(ctx, ctx.right)) {\n ctx.right -= 1;\n } else {\n // Unknown tags\n if (ctx.left + 2 < ctx.right && ctx.right >= ctx.tokens.length - 1) {\n ctx.tags.push(ctx.tokens[ctx.right].text);\n ctx.right -= 1;\n } else {\n break;\n }\n }\n }\n\n {\n // Handle space splitted tags: 【極影字幕社】★10月新番 在地下城尋求邂逅是否搞錯了什麼 第五季 豐饒的女神篇 第06話 BIG5 1080P MP4(字幕社招人內詳)\n const token = ctx.tokens[ctx.right];\n const text = token.text;\n const sepearators = [' ', '★'];\n for (const sep of sepearators) {\n const parts = text.split(sep);\n if (parts.length > 1) {\n let changed = 0;\n while (parts.length > 1) {\n const part = parts[parts.length - 1];\n // Skip single number\n if (/^\\d+$/.test(part)) {\n break;\n }\n if (\n matchSingleTag(ctx, part) ||\n matchEpiodes(ctx, part) ||\n matchMultipleTags(ctx, part)\n ) {\n changed++;\n parts.pop();\n } else {\n break;\n }\n }\n if (changed > 1) {\n const trimmed = parts.join(sep);\n ctx.tokens[ctx.right] = new Token(trimmed, token.left, token.right);\n }\n if (changed > 0) {\n break;\n }\n }\n }\n }\n}\n\nexport function parseLeftTags(ctx: Context) {\n while (ctx.left < ctx.right) {\n if (parseTag(ctx, ctx.left)) {\n ctx.left += 1;\n } else {\n break;\n }\n }\n\n // Match prefix\n {\n const token = ctx.tokens[ctx.left];\n const text = token.text;\n // 【极影字幕社】 ★10月新番\n const match = /^★?(\\d\\d?)月新?番★?/.exec(text);\n if (match) {\n const matched = match[0];\n const month = +match[1];\n ctx.update('month', month);\n ctx.tokens[ctx.left] = token.slice(matched.length);\n if (ctx.tokens[ctx.left].text.length === 0) {\n ctx.left += 1;\n }\n }\n }\n {\n const token = ctx.tokens[ctx.left];\n const text = token.text;\n const match = /^★?(剧场版|劇場版)★?/.exec(text);\n if (match) {\n const matched = match[0];\n const type = match[1];\n ctx.update('type', type);\n ctx.tokens[ctx.left] = token.slice(matched.length);\n if (ctx.tokens[ctx.left].text.length === 0) {\n ctx.left += 1;\n }\n }\n }\n}\n\nexport function parseSuffixSeasonOrEpisodes(ctx: Context, text: string) {\n while (true) {\n let found = false;\n // Ends with: [45]\n if (RevWrappers.has(text[text.length - 1])) {\n const leftWrapper = RevWrappers.get(text[text.length - 1])!;\n const leftIdx = text.lastIndexOf(leftWrapper);\n if (leftIdx !== -1) {\n const maybe = text.slice(leftIdx + 1, text.length - 1);\n if (maybe.length > 0) {\n if (matchSingleTag(ctx, maybe) || (!ctx.hasEpisode && matchEpiodes(ctx, maybe))) {\n text = text.slice(0, text.length - maybe.length - 2).trimEnd();\n found = true;\n }\n }\n }\n }\n\n //\n for (const [re, fn] of SuffixSeasonOrEpisodesRes) {\n const res = re.exec(text);\n if (res && fn(res, ctx)) {\n text = text.slice(0, text.length - res[0].length).trimEnd();\n found = true;\n break;\n }\n }\n if (!found) break;\n }\n\n return text;\n}\n","import { Context } from './context';\nimport { parseSuffixEpisodes } from './episodes';\nimport { parseSuffixSeasonOrEpisodes } from './keyword';\n\nexport function parseFansub(ctx: Context) {\n // [fansub] title\n if (ctx.left + 1 > ctx.right) {\n return false;\n }\n\n const token = ctx.tokens[ctx.left];\n if (token.isWrapped) {\n const text = token.text;\n\n let found = false;\n const seps = ['&', '·'];\n for (const sep of seps) {\n const [name, ...collab] = text.split(sep);\n\n if (collab.length > 0) {\n // Hack: [jibaketa合成&壓制]\n if (collab.length === 1 && collab[0].endsWith('壓制')) {\n break;\n }\n\n found = true;\n ctx.update2('fansub', 'name', name);\n ctx.update2('fansub', 'collab', collab);\n break;\n }\n }\n\n if (!found) {\n ctx.update2('fansub', 'name', text);\n }\n\n ctx.left += 1;\n\n return true;\n }\n\n return false;\n}\n\nexport function parseTitle(ctx: Context) {\n // 1. Parse suffix episodes\n parseSuffixEpisodes(ctx);\n\n // 2. Parse titles\n const rest = ctx.tokens.slice(ctx.left, ctx.right + 1);\n if (rest.length === 0) return false;\n\n // 2.1. Try split multiple titles\n let found = false;\n\n const matchParts = (parts: string[]) => {\n const [title, ...other] = parts;\n\n const trimmedTitle = parseSuffixSeasonOrEpisodes(ctx, title);\n const trimmedOther = other\n .map((t) => parseSuffixSeasonOrEpisodes(ctx, t))\n .map((t) => t.trim())\n .filter((t) => !!t && t !== trimmedTitle);\n\n ctx.update('title', trimmedTitle);\n if (trimmedOther.length > 0) {\n ctx.update('titles', trimmedOther);\n }\n };\n\n // [xxx][yyy]\n if (rest.length > 1 && rest.every((t) => t.isWrapped)) {\n matchParts(rest.map((t) => t.text));\n found = true;\n }\n\n if (!found) {\n const text = rest.length === 1 ? rest[0].text : rest.map((t) => t.toString()).join('');\n\n const separators = ['/', '\\\\'];\n\n for (const sep of separators) {\n const parts = splitText(text, sep)\n .map((t) => t.trim())\n .filter((t) => !!t);\n if (parts.length > 1) {\n matchParts(parts);\n found = true;\n break;\n }\n }\n\n // @hack ANi\n if (!found && ctx.options.fansub === 'ANi') {\n const parts = splitOnce(text, ' - ')\n .map((t) => t.trim())\n .filter((t) => !!t);\n if (parts.length > 1) {\n matchParts(parts);\n found = true;\n }\n }\n\n if (!found) {\n const trimmed = parseSuffixSeasonOrEpisodes(ctx, text);\n ctx.update('title', trimmed);\n }\n }\n\n return true;\n}\n\nfunction splitText(text: string, sep: string) {\n const parts = text.split(sep);\n const ans = [];\n for (let i = 0; i < parts.length; i++) {\n if (i === 0) {\n ans.push(parts[i]);\n } else {\n // 【喵萌奶茶屋】★10月新番★[乱马 1/2 2024年版 / Ranma ½ / Ranma 1/2 (2024)][10][1080p][简日双语][招募翻译]\n if (sep === '/' && /\\d$/.test(parts[i - 1]) && /^\\d/.test(parts[i])) {\n ans.pop();\n ans.push(parts[i - 1] + '/' + parts[i]);\n } else {\n ans.push(parts[i]);\n }\n }\n }\n return ans;\n}\n\nfunction splitOnce(text: string, separator: string): [string, string] {\n const found = text.indexOf(separator);\n if (found === -1) {\n return [text, ''];\n }\n const first = text.slice(0, found);\n const second = text.slice(found + separator.length);\n return [first, second];\n}\n","import type { ParseOptions, ParseResult } from './types';\n\nimport { Context } from './context';\nimport { tokenize } from './tokenizer';\nimport { parseLeftTags, parseRightTags } from './keyword';\nimport { parseFansub, parseTitle } from './title';\n\nexport function parse(title: string, options: ParseOptions = {}): ParseResult | undefined {\n const tokens = tokenize(title);\n if (tokens.length === 0) return undefined;\n\n const context = new Context(tokens, options);\n\n // 1. Parse right tags\n parseRightTags(context);\n // 2. Parse left tags\n parseLeftTags(context);\n // 3. Parse fansub\n parseFansub(context);\n parseLeftTags(context);\n // 4. Parse title\n if (!parseTitle(context)) {\n return undefined;\n }\n\n // 6. Return result\n const result = context.validate();\n return result ? postprocess(result) : undefined;\n}\n\nfunction postprocess(result: ParseResult) {\n if (result.fansub?.name === 'ANi') {\n if (result.title && result.titles && result.titles.length === 1) {\n const t1 = result.title;\n const t2 = result.titles[0];\n result.title = t2;\n result.titles = [t1];\n }\n }\n return result;\n}\n"],"names":[],"mappings":"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