diff --git a/dist/web/index.js b/dist/player/index.js similarity index 99% rename from dist/web/index.js rename to dist/player/index.js index 9088627..4c23dae 100644 --- a/dist/web/index.js +++ b/dist/player/index.js @@ -285,7 +285,7 @@ } }); - script.__file = "src/web/components/player.component.vue"; + script.__file = "src/player/components/player.component.vue"; function normalizeTimecode(timecode) { const [hh, mm, ss, ms] = timecode.split(/[^\d]+/); diff --git a/dist/player/index.js.map b/dist/player/index.js.map new file mode 100644 index 0000000..d0f346d --- /dev/null +++ b/dist/player/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sources":["../../src/common/timecodes.ts","../../src/common/captions.ts","../../src/player/caption-renderer.ts","../../src/player/player.ts","../../src/player/components/player.component.vue","../../src/common/dynamic-css-rules.ts","../../src/player/css-processor.ts","../../src/player/index.ts"],"sourcesContent":["export class Timecode {\n public readonly hours: number;\n public readonly minutes: number;\n public readonly seconds: number;\n public readonly millis: number;\n\n constructor(millis: number) {\n this.millis = millis % 1000;\n\n this.hours = Math.floor(millis / 3_600_000);\n const remainingMillisAfterHours = millis % 3_600_000;\n this.minutes = Math.floor(remainingMillisAfterHours / 60_000);\n const remainingMillisAfterMinutes = remainingMillisAfterHours % 60_000;\n this.seconds = Math.floor(remainingMillisAfterMinutes / 1000);\n }\n\n public get hh(): string {\n return String(this.hours).padStart(2, '0');\n }\n\n public get mm(): string {\n return String(this.minutes).padStart(2, '0');\n }\n\n public get ss(): string {\n return String(this.seconds).padStart(2, '0');\n }\n public get SSS(): string {\n return String(this.millis).padStart(3, '0');\n }\n\n public get asString(): string {\n return `${this.hh}:${this.mm}:${this.ss},${this.SSS}`;\n }\n}\n\nexport function toMillis(timecodes: string): number {\n const parts = timecodes.split(/[:,]/).map(Number);\n\n const hours = parts[0];\n const minutes = parts[1];\n const seconds = parts[2];\n const milliseconds = parts[3];\n\n return hours * 3_600_000 // hours to millis\n + minutes * 60_000 // minutes to millis\n + seconds * 1000 // second to millis\n + milliseconds;\n}","import {toMillis} from './timecodes';\n\nconst indexLinePattern = /^\\d+$/;\nconst timecodesLinePattern = /^(\\d{2}:\\d{2}:\\d{2},\\d{3}) --> (\\d{2}:\\d{2}:\\d{2},\\d{3})$/;\nconst highlightedWordPattern = /^\\[(.+)](?:\\((\\w+)\\))?$/;\n\nexport interface Word {\n rawWord: string;\n isHighlighted: boolean;\n isBeforeHighlighted: boolean;\n isAfterHighlighted: boolean;\n highlightClass?: string;\n}\n\nexport interface Caption {\n index: number;\n startTimeMs: number;\n endTimeMs: number;\n words: Word[];\n}\n\nexport function haveSameWords(caption1: Caption, caption2: Caption): boolean {\n if (caption1.words.length != caption2.words.length) {\n return false;\n }\n\n for (let i =0; i < caption1.words.length; i++) {\n if (caption1.words[i].rawWord != caption2.words[i].rawWord) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function readCaptions(srtContent: string): Caption[] {\n const lines = srtContent.split('\\n');\n const captions: Caption[] = [];\n\n let index: number = 0;\n let timecodesStart: string | null = null;\n let timecodesEnd: string | null = null;\n\n for (const line of lines) {\n let match;\n if ((match = line.match(indexLinePattern))) {\n index = Number(line);\n } else if ((match = line.match(timecodesLinePattern))) {\n timecodesStart = match[1];\n timecodesEnd = match[2];\n } else if (line.length) {\n const start = toMillis(timecodesStart!);\n const end = toMillis(timecodesEnd!);\n\n const words = readWords(line);\n\n captions.push({\n index,\n words,\n startTimeMs: start,\n endTimeMs: end,\n });\n }\n }\n\n return captions;\n}\n\nexport function readWords(text: string): Word[] {\n const words = splitText(text);\n const highlightedIndex = words.findIndex(word => word.match(highlightedWordPattern));\n\n const res: Word[] = [];\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const match = word.match(highlightedWordPattern);\n const rawWord = match ? match[1] : word;\n const highlightClass = match && match[2] ? match[2] : null;\n\n const isHighlighted = Boolean(match);\n const isBeforeHighlighted = Boolean(~highlightedIndex && !isHighlighted && i < highlightedIndex);\n const isAfterHighlighted = Boolean(~highlightedIndex && !isHighlighted && i > highlightedIndex);\n\n const wordObject: Word = {\n rawWord,\n isHighlighted,\n isBeforeHighlighted,\n isAfterHighlighted,\n };\n\n if (highlightClass) {\n wordObject.highlightClass = highlightClass;\n }\n\n res.push(wordObject);\n }\n\n return res;\n}\n\nexport function splitText(text: string): string[] {\n const words: string[] = [];\n\n let currentWord = '';\n let isCurrentHighlighted = false;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const isWhitespace = /^\\s$/.test(char);\n const isPunctuation = /[,.!?]/.test(char);\n\n if (!isWhitespace) {\n if (!isPunctuation) {\n currentWord += char;\n switch (char) {\n case '[':\n case '(':\n isCurrentHighlighted = true;\n break;\n case ']':\n case ')':\n isCurrentHighlighted = false;\n break;\n }\n } else {\n if (currentWord) {\n currentWord += char;\n } else {\n // Attach punctuation mark to the previous word\n words[words.length - 1] += ' ' + char;\n }\n }\n } else {\n // char is a whitespace\n if (isCurrentHighlighted) {\n currentWord += char;\n } else if (currentWord) {\n words.push(currentWord);\n currentWord = '';\n }\n }\n }\n\n if (currentWord) {\n words.push(currentWord);\n }\n\n return words;\n}","import {Caption, Word} from '../common/captions';\nimport {CssProcessor} from './css-processor';\n\nexport class CaptionRenderer {\n public constructor(private readonly cssProcessor: CssProcessor) {\n }\n\n public renderCaption(caption: Caption): HTMLDivElement {\n const captionDiv = document.createElement('div');\n captionDiv.setAttribute('id', `caption_${caption.index}`);\n captionDiv.setAttribute('class', 'caption');\n\n caption.words\n .map(word => this.renderWord(word, caption))\n .forEach(spanElem => captionDiv.appendChild(spanElem));\n\n const captionWords = caption.words.map(word => word.rawWord);\n return this.cssProcessor.applyDynamicClasses(captionDiv, caption.index, caption.startTimeMs, captionWords);\n }\n\n private renderWord(word: Word, caption: Caption): HTMLSpanElement {\n const cssClasses = CaptionRenderer.wordSpanClasses(word);\n const wordSpan = document.createElement('span');\n wordSpan.textContent = word.rawWord;\n wordSpan.classList.add(...cssClasses);\n\n return this.cssProcessor.applyDynamicClasses(wordSpan, caption.index, caption.startTimeMs, [ word.rawWord ]);\n }\n\n public static wordSpanClasses(word: Word): Set {\n const cssClasses = new Set([ 'word' ]);\n\n if (word.isHighlighted) {\n cssClasses.add(word.highlightClass || 'highlighted');\n } if (word.isBeforeHighlighted) {\n cssClasses.add('before-highlighted');\n } if (word.isAfterHighlighted) {\n cssClasses.add('after-highlighted');\n }\n\n return cssClasses;\n }\n}","import {Caption, haveSameWords} from '../common/captions';\nimport {CaptionRenderer} from './caption-renderer';\nimport {CssProcessor} from './css-processor';\n\nexport class Player {\n public onStop = () => {};\n\n private readonly captionsContainer: HTMLDivElement;\n private readonly rendered: HTMLDivElement[] = [];\n private timeoutIds: NodeJS.Timeout[] = [];\n private displayedCaptionId = 0;\n\n constructor(private readonly videoElem: HTMLElement,\n private readonly captions: Caption[],\n private readonly cssProcessor: CssProcessor,\n renderer: CaptionRenderer) {\n this.captionsContainer = this.videoElem.querySelector('.captions')!;\n\n for (let i = 0; i < captions.length; i++) {\n const caption = captions[i];\n this.rendered[caption.index] = i > 0 && haveSameWords(caption, captions[i - 1])\n ? this.rendered[caption.index - 1]\n : renderer.renderCaption(caption);\n }\n }\n\n public play() {\n this.rendered.forEach(captionElem => captionElem.remove());\n\n if (this.captions.length === 0) {\n return;\n }\n\n for (let i = 0; i < this.captions.length; i++) {\n const caption = this.captions[i];\n const displayTimeoutId = setTimeout(() => {\n this.displayCaption(caption.index);\n }, caption.startTimeMs);\n this.timeoutIds.push(displayTimeoutId);\n\n if (i < this.captions.length - 1) {\n const nextCaption = this.captions[i + 1];\n\n if (!haveSameWords(caption, nextCaption)) {\n const hideTimeoutId = setTimeout(() => {\n this.hideCaption(caption.index);\n }, caption.endTimeMs);\n this.timeoutIds.push(hideTimeoutId);\n }\n } else {\n const hideTimeoutId = setTimeout(() => {\n this.hideCaption(caption.index);\n this.stop();\n }, caption.endTimeMs);\n this.timeoutIds.push(hideTimeoutId);\n }\n }\n }\n\n public stop() {\n if (this.displayedCaptionId) {\n this.rendered[this.displayedCaptionId].remove();\n this.displayedCaptionId = 0;\n }\n\n while (this.timeoutIds.length) {\n clearTimeout(this.timeoutIds.pop());\n }\n\n this.onStop();\n }\n\n public prec() {\n if (!this.isBeginning) {\n let precId = this.displayedCaptionId - 1;\n if (precId) {\n this.displayCaption(precId);\n } else {\n this.hideCaption(this.displayedCaptionId)\n }\n }\n }\n\n public next() {\n if (!this.isEnd) {\n this.displayCaption(this.displayedCaptionId + 1);\n }\n }\n\n public get isBeginning(): boolean {\n return this.displayedCaptionId === 0;\n }\n\n public get isEnd(): boolean {\n return this.displayedCaptionId === this.captions.length\n }\n\n private displayCaption(index: number) {\n if (this.displayedCaptionId === index) {\n return; // Displayed already, do nothing\n }\n\n if (this.displayedCaptionId) {\n const displayedCaption = this.captions[this.displayedCaptionId - 1];\n const nextCaption = this.captions[index - 1];\n\n if (haveSameWords(displayedCaption, nextCaption)) {\n const renderedCaption = this.rendered[this.displayedCaptionId];\n\n const captionWords = nextCaption.words.map(word => word.rawWord);\n this.cssProcessor.applyDynamicClasses(renderedCaption, index, nextCaption.startTimeMs, captionWords);\n\n const renderedWords = renderedCaption.querySelectorAll('.word');\n for (let i = 0; i < renderedWords.length; i++) {\n const word = nextCaption.words[i];\n const renderedWord = renderedWords[i] as HTMLElement;\n\n const cssClasses = CaptionRenderer.wordSpanClasses(word);\n const existingClasses = new Set([...renderedWord.classList.values()]);\n\n const classesToRemove = existingClasses.difference(cssClasses);\n const classesToAdd = cssClasses.difference(existingClasses);\n\n renderedWord.classList.remove(...classesToRemove);\n renderedWord.classList.add(...classesToAdd);\n\n this.cssProcessor.applyDynamicClasses(renderedWord, index, nextCaption.startTimeMs, [ word.rawWord ]);\n }\n } else {\n this.rendered[this.displayedCaptionId].remove();\n this.captionsContainer.appendChild(this.rendered[index]);\n }\n } else {\n this.captionsContainer.appendChild(this.rendered[index]);\n }\n\n this.dynamicallyStyleContainers(index);\n this.displayedCaptionId = index;\n }\n\n private dynamicallyStyleContainers(index: number) {\n this.videoElem.setAttribute('class', '');\n this.captionsContainer.setAttribute('class', 'captions');\n\n const caption = this.captions[index - 1];\n const captionWords = caption.words.map(word => word.rawWord);\n this.cssProcessor.applyDynamicClasses(this.videoElem, index, caption.startTimeMs, captionWords);\n this.cssProcessor.applyDynamicClasses(this.captionsContainer, index, caption.startTimeMs, captionWords);\n }\n\n private hideCaption(index: number) {\n if (this.displayedCaptionId != index) {\n return; // Removed already, do nothing\n }\n\n this.rendered[index].remove();\n this.displayedCaptionId = 0;\n }\n}","\n\n","import {toMillis} from '../common/timecodes';\n\nexport type FilterType = 'indexes' | 'timecodes' | 'words';\n\nexport interface Filter {\n cssClass: string;\n type: FilterType;\n args: string[];\n}\n\nexport function normalizeTimecode(timecode: string): string {\n const [ hh, mm, ss, ms ] = timecode.split(/[^\\d]+/);\n return `${hh}:${mm}:${ss}.${ms}`;\n}\n\nexport abstract class AbstractDynamicCssRule {\n protected constructor(protected readonly targetSelectors: string[],\n public readonly appliedCssClass: string) {\n }\n\n public isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n let targetClasses = target.getAttribute('class')?.split(' ') || [];\n\n for (const targetSelector of this.targetSelectors) {\n if (targetSelector.startsWith('#')) {\n const idSelector = targetSelector.slice(1);\n if (target.getAttribute('id') != idSelector) {\n return false;\n }\n } else if (targetSelector.startsWith('.')) {\n const classSelector = targetSelector.slice(1);\n if (!targetClasses.includes(classSelector)) {\n return false;\n }\n } else {\n throw new Error(`Unsupported target selector: '${targetSelector}'`);\n }\n }\n\n return true;\n }\n}\n\nexport class IndexesDynamicCssRule extends AbstractDynamicCssRule {\n constructor(targetSelectors: string[],\n appliedCssClass: string,\n private readonly startIndexInclusive: number,\n private readonly endIndexInclusive?: number) {\n super(targetSelectors, appliedCssClass);\n }\n\n isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n return super.isApplied(target, captionIndex, timeMs, words)\n && this.startIndexInclusive <= captionIndex\n && (this.endIndexInclusive ? this.endIndexInclusive >= captionIndex : true);\n }\n}\n\nexport class TimecodesDynamicCssRule extends AbstractDynamicCssRule {\n constructor(targetSelectors: string[],\n appliedCssClass: string,\n private readonly startTimeMsInclusive: number,\n private readonly endTimeMsInclusive?: number) {\n super(targetSelectors, appliedCssClass);\n }\n\n isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n return super.isApplied(target, captionIndex, timeMs, words)\n && this.startTimeMsInclusive <= timeMs\n && (this.endTimeMsInclusive ? this.endTimeMsInclusive >= timeMs : true);\n }\n}\n\nexport function createDynamicCssRule(targetSelectors: string[], filter: Filter): AbstractDynamicCssRule {\n switch (filter.type) {\n case 'indexes':\n const [ startIndex, endIndex ] = filter.args.map(arg => Number(arg));\n return new IndexesDynamicCssRule(targetSelectors, filter.cssClass, startIndex, endIndex);\n case 'timecodes':\n const [ startMs, endMs ] = filter.args.map(normalizeTimecode).map(toMillis);\n return new TimecodesDynamicCssRule(targetSelectors, filter.cssClass, startMs, endMs);\n default:\n throw new Error(`Unknown filter type '${filter.type}'!`);\n }\n}","import {AbstractDynamicCssRule, createDynamicCssRule, Filter, FilterType} from '../common/dynamic-css-rules';\n\nconst dynamicCssClassPrefix = 'pup-';\nconst dynamicCssClassPattern = /^\\.pup-(\\w+)((?:-[^-]+)+)$/;\n\nexport class CssProcessor {\n private readonly dynamicCssRules: AbstractDynamicCssRule[] = [];\n\n constructor() {\n for (const styleSheet of document.styleSheets) {\n for (const styleRule of styleSheet.cssRules) {\n const selectorText = (styleRule as CSSStyleRule).selectorText || '';\n\n if (selectorText.includes('.pup-')) {\n const selectors = CssProcessor.parseSelectors(selectorText);\n const targetSelectors: string[] = [];\n let filter: Filter | null = null;\n\n for (const selector of selectors) {\n if (selector.match(dynamicCssClassPattern)) {\n if (filter) {\n throw new Error(\n `Only one dynamic CSS class is allowed per style rule. \n Two dynamic classes were found: .${filter.cssClass} and ${selector}`);\n }\n\n filter = CssProcessor.parseFilter(selector);\n } else {\n targetSelectors.push(selector);\n }\n }\n\n const rule = createDynamicCssRule(targetSelectors, filter!);\n this.dynamicCssRules.push(rule);\n }\n }\n }\n }\n\n public applyDynamicClasses(target: T, captionIndex: number, timeMs: number, words: string[]): T {\n const dynamicCssClasses = this.dynamicCssClasses(target, captionIndex, timeMs, words);\n const existingDynamicClasses = CssProcessor.getDynamicCssClassesFromElem(target);\n\n const classesToRemove = existingDynamicClasses.difference(dynamicCssClasses);\n const classesToAdd = dynamicCssClasses.difference(classesToRemove);\n\n target.classList.remove(...classesToRemove);\n target.classList.add(...classesToAdd);\n\n return target;\n }\n\n private dynamicCssClasses(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): Set {\n const cssClasses = this.dynamicCssRules\n .filter(rule => rule.isApplied(target, captionIndex, timeMs, words))\n .map(rule => rule.appliedCssClass);\n return new Set(cssClasses);\n }\n\n public static getDynamicCssClassesFromElem(elem: HTMLElement): Set {\n const dynamicCssClasses = [...elem.classList.values()]\n .filter(cssClass => cssClass.startsWith(dynamicCssClassPrefix));\n return new Set(dynamicCssClasses);\n }\n\n static parseFilter(dynamicCssClass: string): Filter {\n const match = dynamicCssClass.match(dynamicCssClassPattern);\n\n if (!match) {\n throw new Error(`CSS class ${dynamicCssClass} do not match required pattern!`);\n }\n\n const cssClass = dynamicCssClass.slice(1);\n const filterType = match[1] as FilterType;\n const filterArgs = match[2].split('-').slice(1);\n\n return {\n cssClass,\n type: filterType,\n args: filterArgs,\n }\n }\n\n static parseSelectors(selectorText: string): string[] {\n const selectors: string[] = [];\n let currentToken = '';\n let lastIsEscaped = false;\n\n for (let i = 0; i < selectorText.length; i++) {\n const char = selectorText[i];\n if ((char === '.' || char === '#') && !lastIsEscaped) {\n if (currentToken) {\n selectors.push(currentToken);\n }\n currentToken = char;\n } else if (char === '\\\\') {\n currentToken += char;\n lastIsEscaped = true;\n } else if (lastIsEscaped) {\n currentToken += char;\n lastIsEscaped = false;\n } else {\n currentToken += char;\n }\n }\n\n if (currentToken) {\n selectors.push(currentToken);\n }\n\n return selectors;\n }\n}\n","import {createApp} from 'vue';\nimport {Player} from './player';\nimport PlayerComponent from './components/player.component.vue';\nimport {CssProcessor} from './css-processor';\nimport {CaptionRenderer} from './caption-renderer';\n\nwindow.ready = new Promise((resolve, reject) => {\n window.onload = () => {\n const videoElem = document.getElementById('video');\n const cssProcessor = new CssProcessor();\n const renderer = new CaptionRenderer(cssProcessor);\n window.Player = new Player(videoElem!, window.captions, cssProcessor, renderer);\n\n if (window.playerArgs.isPreview) {\n createApp({})\n .component('player', PlayerComponent)\n .mount('#player-controller');\n }\n\n resolve();\n };\n});\n"],"names":["reactive","createApp","PlayerComponent"],"mappings":"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"} \ No newline at end of file diff --git a/dist/script/index.js b/dist/script/index.js index dd7c9a4..1f4043c 100644 --- a/dist/script/index.js +++ b/dist/script/index.js @@ -185,7 +185,7 @@ var packageJson = { const assetsFolder = path__namespace.join(__dirname, '..', '..', 'assets'); const defaultStylesCss = path__namespace.join(assetsFolder, 'captions.css'); const indexHtml = path__namespace.join(assetsFolder, 'index.html'); -const indexJs = path__namespace.join(__dirname, '..', 'web', 'index.js'); +const indexJs = path__namespace.join(__dirname, '..', 'player', 'index.js'); const nodeModules = path__namespace.join(__dirname, '..', '..', 'node_modules'); function parseIntAndAssert(...assertions) { diff --git a/dist/script/index.js.map b/dist/script/index.js.map index 61755f5..23ef668 100644 --- a/dist/script/index.js.map +++ b/dist/script/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../node_modules/@commander-js/extra-typings/index.js","../../node_modules/@commander-js/extra-typings/esm.mjs","../../src/script/assets.ts","../../src/script/cli.ts","../../src/script/work-dir.ts","../../src/script/stats-printer.ts","../../src/script/abstract-renderer.ts","../../src/script/step-renderer.ts","../../src/script/abstract-recorder.ts","../../src/script/real-time-recorder.ts","../../src/script/real-time-renderer.ts","../../src/script/step-recorder.ts","../../src/common/timecodes.ts","../../src/common/captions.ts","../../src/common/web-server.ts","../../src/script/index.ts"],"sourcesContent":["const commander = require('commander');\n\nexports = module.exports = {};\n\n// Return a different global program than commander,\n// and don't also return it as default export.\nexports.program = new commander.Command();\n\n/**\n * Expose classes. The FooT versions are just types, so return Commander original implementations!\n */\n\nexports.Argument = commander.Argument;\nexports.Command = commander.Command;\nexports.CommanderError = commander.CommanderError;\nexports.Help = commander.Help;\nexports.InvalidArgumentError = commander.InvalidArgumentError;\nexports.InvalidOptionArgumentError = commander.InvalidArgumentError; // Deprecated\nexports.Option = commander.Option;\n\n// In Commander, the create routines end up being aliases for the matching\n// methods on the global program due to the (deprecated) legacy default export.\n// Here we roll our own, the way Commander might in future.\nexports.createCommand = (name) => new commander.Command(name);\nexports.createOption = (flags, description) =>\n new commander.Option(flags, description);\nexports.createArgument = (name, description) =>\n new commander.Argument(name, description);\n","import extraTypingsCommander from './index.js';\n\n// wrapper to provide named exports for ESM.\nexport const {\n program,\n createCommand,\n createArgument,\n createOption,\n CommanderError,\n InvalidArgumentError,\n InvalidOptionArgumentError, // deprecated old name\n Command,\n Argument,\n Option,\n Help,\n} = extraTypingsCommander;\n","import * as path from 'path';\n\nexport const assetsFolder = path.join(__dirname, '..', '..', 'assets');\nexport const defaultStylesCss = path.join(assetsFolder, 'captions.css');\nexport const indexHtml = path.join(assetsFolder, 'index.html');\n\nexport const indexJs = path.join(__dirname, '..', 'web', 'index.js');\n\nexport const nodeModules = path.join(__dirname, '..', '..', 'node_modules');\n","import {Command} from '@commander-js/extra-typings';\nimport packageJson from '../../package.json';\nimport {defaultStylesCss} from './assets';\nimport * as cliProgress from 'cli-progress';\nimport * as path from 'path';\n\nexport interface Args {\n srtInputFile: string;\n movOutputFile: string;\n videoWidth: number;\n videoHeight: number;\n fps: number;\n styleFile: string;\n css3Animations: boolean;\n isPreview: boolean;\n}\n\nfunction parseIntAndAssert(...assertions: ((v: number) => void)[]): (v: string) => number {\n return (value: string) => {\n const int = parseInt(value, 10);\n assertions.forEach(assertion => assertion(int));\n return int;\n }\n}\n\nfunction assertPositive(option: string): (v: number) => void {\n return (value: number) => {\n if (value < 0) {\n throw new Error(`${option} should be positive!`);\n }\n };\n}\n\nfunction assertMinMax(option: string, min: number, max: number): (v: number) => void {\n return (value: number) => {\n if (value < min || value > max) {\n throw new Error(`${option} should be between ${min} and ${max}!`);\n }\n };\n}\n\nfunction assertFileExtension(ext: string): (v: string) => void {\n return (value: string) => {\n if (!value.endsWith(ext)) {\n throw new Error(`File should have extension ${ext}!`);\n }\n return value;\n };\n}\n\nconst program = new Command();\n\nprogram\n .name('pupcaps')\n .description('Tool to add stylish captions to your video.')\n .version(packageJson.version)\n .argument('', 'Path to the input SubRip Subtitle (.srt) file.', assertFileExtension('.srt'))\n .option('-o, --output ',\n 'Full or relative path where the created Films Apple QuickTime (MOV) file should be written. ' +\n 'By default, it will be saved in the same directory as the input subtitle file.',\n assertFileExtension('.mov'))\n .option('-w, --width ',\n 'Width of the video in pixels.',\n parseIntAndAssert(assertPositive('Width')),\n 1080)\n .option('-h, --height ',\n 'Height of the video in pixels.',\n parseIntAndAssert(assertPositive('Height')),\n 1920)\n .option('-r, --fps ',\n 'Specifies the frame rate (FPS) of the output video. Valid values are between 1 and 60.',\n parseIntAndAssert(assertMinMax('FPS', 1, 60)),\n 30)\n .option('-s, --style ',\n 'Full or relative path to the styles .css file. ' +\n 'If not provided, default styles for captions will be used.',\n assertFileExtension('.css'))\n .option('-a, --animate',\n 'Records captions with CSS3 animations. ' +\n 'Note: The recording will run for the entire duration of the video. ' +\n 'Use this option only if your captions involve CSS3 animations.')\n .option('--preview',\n 'Prevents the script from generating a video file. ' +\n 'Instead, captions are displayed in the browser for debugging and preview purposes.')\n .action((inputFile, options: any) => {\n if (!options.output) {\n const fileBasename = (inputFile as any as string).slice(0, -4);\n options.output = `${fileBasename}.mov`;\n }\n\n if (!options.style) {\n options.style = defaultStylesCss;\n } else {\n options.style = path.resolve(options.style);\n }\n });\n\nexport function parseArgs(): Args {\n program.parse();\n const opts = program.opts() as any;\n\n return {\n srtInputFile: program.args[0],\n movOutputFile: opts.output,\n videoWidth: opts.width,\n videoHeight: opts.height,\n fps: opts.fps,\n styleFile: opts.style,\n css3Animations: opts.animate,\n isPreview: opts.preview,\n };\n}\n\nexport function printArgs(args: Args) {\n const styles = args.styleFile === defaultStylesCss\n ? '(Default)'\n : args.styleFile;\n\n const srt = `\n Output: ${args.movOutputFile}\n Width: ${args.videoWidth} px\n Height: ${args.videoHeight} px\n FPS: ${args.fps}\n Styles: ${styles}\n Animations: ${ args.css3Animations ? 'yes' : 'no' }\n `;\n\n console.log(srt);\n}\n\nexport function createProgressBar(): cliProgress.SingleBar {\n return new cliProgress.SingleBar({\n format: 'Progress |{bar}| {percentage}% || {value}/{total} Captions',\n barCompleteChar: '\\u2588',\n barIncompleteChar: '\\u2591',\n hideCursor: true,\n }, cliProgress.Presets.shades_classic);\n}","import * as tmp from 'tmp';\nimport * as path from 'path';\nimport {writeFileSync, symlinkSync, rmSync, mkdirSync} from 'fs';\nimport {Caption} from '../common/captions';\nimport {Args} from './cli';\nimport {indexHtml, indexJs, nodeModules} from './assets';\nimport {PlayerArgs} from '../common/player-args';\n\nexport class WorkDir {\n private readonly workDir = tmp.dirSync({ template: 'pupcaps-XXXXXX' });\n\n constructor(private readonly captions: Caption[],\n private readonly args: Args) {\n }\n\n public setup(): string {\n const index = path.join(this.workDir.name, 'index.html');\n\n symlinkSync(indexHtml, index);\n symlinkSync(indexJs, path.join(this.workDir.name, 'index.js'));\n symlinkSync(this.args.styleFile, path.join(this.workDir.name, 'captions.css'));\n symlinkSync(nodeModules, path.join(this.workDir.name, 'node_modules'));\n\n this.setupCaptions();\n this.setupPlayerArgs();\n this.setupVideoSizeCss();\n\n mkdirSync(this.screenShotsDir);\n\n return index;\n }\n\n public clear() {\n rmSync(this.workDir.name, { recursive: true, force: true });\n }\n\n public get screenShotsDir(): string {\n return path.join(this.workDir.name, 'screenshots');\n }\n\n public get rootDir(): string {\n return this.workDir.name;\n }\n\n private setupVideoSizeCss() {\n const css= `#video {\n width: ${this.args.videoWidth}px;\n height: ${this.args.videoHeight}px;\n }`;\n const videoSizeFile = path.join(this.workDir.name, 'video.size.css');\n\n writeFileSync(videoSizeFile, css);\n }\n\n private setupCaptions() {\n const captionsJs = 'window.captions = ' + JSON.stringify(this.captions, null, 2);\n const captionsJsFile = path.join(this.workDir.name, 'captions.js');\n\n writeFileSync(captionsJsFile, captionsJs);\n }\n\n private setupPlayerArgs() {\n const playerArgs: PlayerArgs = {\n isPreview: this.args.isPreview,\n };\n const argsJs = 'window.playerArgs = ' + JSON.stringify(playerArgs, null, 2);\n const argsJsFile = path.join(this.workDir.name, 'player.args.js');\n\n writeFileSync(argsJsFile, argsJs);\n }\n}","export class StatsPrinter {\n private statsPrinted = false;\n\n public print(stats: Object) {\n const lines = Object\n .entries(stats)\n .map(([key, value]) => `${key}: ${value}`);\n\n if (this.statsPrinted) {\n process.stdout.write(`\\x1b[${lines.length}A`); // Move up N lines\n }\n\n lines.forEach((line) => {\n process.stdout.write(`\\r${line.padEnd(40)}\\n`); // Ensure the line is fully overwritten\n });\n\n this.statsPrinted = true;\n }\n}","import ffmpeg, { setFfmpegPath } from 'fluent-ffmpeg';\nimport {Args} from './cli';\n\n(() => {\n try {\n const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');\n setFfmpegPath(ffmpegInstaller!.path);\n } catch (error) {\n console.warn('Impossible to install FFMpeg. Use system-provided ffmpeg.');\n }\n})();\n\nexport abstract class AbstractRenderer {\n protected constructor(protected readonly args : Args) {\n }\n\n public abstract startEncoding(): void;\n public abstract endEncoding(): void;\n\n protected baseFfmpegCommand(): ffmpeg.FfmpegCommand {\n return ffmpeg()\n .outputOptions([\n '-c:v prores_ks', // codec for Films Apple QuickTime (MOV)\n '-profile:v 4444', // enable the best quality\n '-pix_fmt yuva444p10le', // lossless setting\n '-q:v 0', // lossless setting\n '-vendor ap10' // ensures the output MOV file is compatible with Apple QuickTime\n ])\n .output(this.args.movOutputFile);\n }\n}","import {Args} from './cli';\nimport {PNG, PNGWithMetadata} from 'pngjs';\nimport * as path from 'path';\nimport {appendFileSync, writeFileSync} from 'fs';\nimport {WorkDir} from './work-dir';\nimport {Caption} from '../common/captions';\nimport {StatsPrinter} from './stats-printer';\nimport {AbstractRenderer} from './abstract-renderer';\n\nexport class StepRenderer extends AbstractRenderer {\n private readonly framesFileName: string;\n private readonly emptyFrameFileName: string;\n\n constructor(args : Args,\n private readonly workDir: WorkDir) {\n super(args);\n this.framesFileName = path.join(workDir.screenShotsDir, 'frames.txt');\n this.emptyFrameFileName = path.join(workDir.screenShotsDir, 'empty.png');\n }\n\n public startEncoding() {\n const empty = new PNG({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n colorType: 6,\n });\n writeFileSync(this.emptyFrameFileName, PNG.sync.write(empty));\n }\n\n public addEmptyFrame(durationMs?: number) {\n let frameDef = `file '${this.emptyFrameFileName}'\\n`;\n\n if (durationMs) {\n const durationSec = durationMs / 1000;\n frameDef += `duration ${durationSec}\\n`;\n }\n\n appendFileSync(this.framesFileName, frameDef, 'utf8');\n }\n\n public addFrame(caption: Caption, png: PNGWithMetadata) {\n const screenShotFileName = path.join(this.workDir.screenShotsDir, `screenshot_${caption.index}.png`);\n writeFileSync(screenShotFileName, PNG.sync.write(png));\n\n const durationSec = (caption.endTimeMs - caption.startTimeMs) / 1000;\n\n appendFileSync(\n this.framesFileName,\n `file '${screenShotFileName}'\\nduration ${durationSec}\\n`,\n 'utf8');\n }\n\n public async endEncoding() {\n console.log(`Encoding ${this.args.movOutputFile}...\\n`);\n const statsPrinter = new StatsPrinter();\n\n await new Promise((resolve, reject) => {\n this.baseFfmpegCommand()\n .input(this.framesFileName)\n .inputOptions([\n '-f concat', // concat frames from the frame list\n '-safe 0' // to prevent errors related to unsafe filenames\n ])\n .on('progress', (progress: Object) => {\n statsPrinter.print(progress);\n })\n .on('end', () => {\n console.log(`${this.args.movOutputFile} encoded`);\n resolve(this.args.movOutputFile);\n })\n .on('error', (err: any) => {\n reject(err);\n })\n .run();\n });\n }\n}","import * as puppeteer from 'puppeteer';\nimport {Args} from './cli';\n\nexport abstract class AbstractRecorder {\n protected browser: puppeteer.Browser | null = null;\n protected page: puppeteer.Page | null = null;\n\n protected constructor(protected readonly args: Args) {\n }\n\n public abstract recordCaptionsVideo(indexHtml: string): Promise;\n\n protected async launchBrowser(indexHtml: string): Promise {\n this.browser = await puppeteer.launch({\n args: [\n '--disable-web-security', // Disable CORS\n '--allow-file-access-from-files', // Allow file access\n ],\n headless: true,\n });\n this.page = await this.browser.newPage();\n await this.page.goto(`file://${indexHtml}`);\n await this.page.setViewport({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n });\n await this.page.evaluate(() => {\n return window.ready;\n });\n\n return this.page.$('#video');\n }\n}","import * as puppeteer from 'puppeteer';\nimport {RealTimeRenderer} from './real-time-renderer';\nimport {Args} from './cli';\nimport {AbstractRecorder} from './abstract-recorder';\n\nexport class RealTimeRecorder extends AbstractRecorder {\n constructor(args: Args,\n private readonly videoRenderer: RealTimeRenderer) {\n super(args);\n }\n\n public async recordCaptionsVideo(indexHtml: string) {\n try {\n await this.launchBrowser(indexHtml);\n const cdpSession = await this.page!.createCDPSession();\n\n await cdpSession.send(\n 'Emulation.setDefaultBackgroundColorOverride',\n { color: { r: 0, g: 0, b: 0, a: 0 } }\n );\n await cdpSession.send('Animation.setPlaybackRate', {\n playbackRate: 1,\n });\n\n cdpSession.on('Page.screencastFrame',\n (frame) => this.handleScreenCastFrame(cdpSession, frame));\n\n this.videoRenderer.startEncoding();\n\n await cdpSession.send('Page.startScreencast', {\n everyNthFrame: 1,\n format: 'png',\n quality: 100,\n });\n\n await this.page!.evaluate(() => {\n return new Promise((resolve) => {\n window.Player.onStop = resolve;\n window.Player.play();\n })\n });\n\n await cdpSession.send('Page.stopScreencast');\n\n this.videoRenderer.endEncoding();\n } catch (error) {\n console.error('Error during Puppeteer operation:', error);\n } finally {\n await this.browser?.close();\n }\n }\n\n private async handleScreenCastFrame(cdpSession: puppeteer.CDPSession,\n frame: puppeteer.Protocol.Page.ScreencastFrameEvent) {\n const { sessionId, data } = frame;\n await cdpSession.send('Page.screencastFrameAck', { sessionId });\n const frameBuffer = Buffer.from(data, 'base64');\n this.videoRenderer.addFrame(frameBuffer);\n }\n}","import {PassThrough} from 'stream';\nimport {PNG} from 'pngjs';\nimport {Args} from './cli';\nimport {StatsPrinter} from './stats-printer';\nimport {AbstractRenderer} from './abstract-renderer';\n\nexport class RealTimeRenderer extends AbstractRenderer {\n private inputStream: PassThrough | null = null;\n private intervalId: NodeJS.Timeout | null = null;\n private lastFrame: Buffer;\n\n constructor(args: Args) {\n super(args);\n const empty = new PNG({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n colorType: 6,\n });\n this.lastFrame = PNG.sync.write(empty);\n }\n\n public startEncoding() {\n this.inputStream = new PassThrough();\n const statsPrinter = new StatsPrinter();\n\n const command = this.baseFfmpegCommand()\n .input(this.inputStream)\n .inputOptions([\n '-f image2pipe', // Format of input frames\n '-pix_fmt yuva444p10le', // Lossless setting\n `-s ${this.args.videoWidth}x${this.args.videoHeight}`, // Frame size\n `-r ${this.args.fps}`, // Framerate\n ])\n .on('start', () => {\n console.log('FFmpeg process started.');\n })\n .on('progress', (progress) => {\n statsPrinter.print(progress);\n })\n .on('end', () => {\n console.log('FFmpeg process completed.');\n })\n .on('error', (err) => {\n console.error('An error occurred:', err.message);\n });\n\n command.run();\n\n // Produce frames in required rate\n const intervalDuration = Math.round(1000 / 30);\n this.intervalId = setInterval(() => {\n this.inputStream!.write(this.lastFrame);\n }, intervalDuration);\n }\n\n public addFrame(frame: Buffer) {\n this.lastFrame = frame;\n }\n\n public endEncoding() {\n clearTimeout(this.intervalId!);\n this.inputStream!.end();\n }\n}","import * as puppeteer from 'puppeteer';\nimport * as cliProgress from 'cli-progress';\nimport {PNG, PNGWithMetadata} from 'pngjs';\nimport {Caption} from '../common/captions';\nimport {StepRenderer} from './step-renderer';\nimport {Args} from './cli';\nimport {AbstractRecorder} from './abstract-recorder';\n\nexport class StepRecorder extends AbstractRecorder {\n constructor(args: Args,\n private readonly captions: Caption[],\n private readonly renderer: StepRenderer,\n private readonly progressBar: cliProgress.SingleBar) {\n super(args);\n }\n\n public async recordCaptionsVideo(indexHtml: string) {\n this.progressBar.start(this.captions.length, 0);\n\n try {\n const videoElem = await this.launchBrowser(indexHtml);\n\n this.renderer.startEncoding();\n\n // Add empty frame before captions starts\n const beginningTime = this.captions[0].startTimeMs;\n this.renderer.addEmptyFrame(beginningTime);\n\n for (let i = 0; i < this.captions.length; i++) {\n const caption = this.captions[i];\n\n await this.nextStep();\n\n const screenShot = await this.takeScreenShot(videoElem!);\n this.renderer.addFrame(caption, screenShot);\n\n // Add delay before the next frame\n if (i < this.captions.length - 1) {\n const idleDelay = this.captions[i + 1].startTimeMs - caption.endTimeMs;\n if (idleDelay) {\n this.renderer.addEmptyFrame(idleDelay);\n }\n }\n\n this.progressBar.increment();\n }\n\n // Finish with en empty frame\n this.renderer.addEmptyFrame();\n\n this.progressBar.stop();\n await this.renderer.endEncoding();\n } catch (error) {\n console.error('Error during Puppeteer operation:', error);\n } finally {\n await this.browser?.close();\n }\n }\n\n private async nextStep() {\n await this.page!.evaluate(() => {\n window.Player.next();\n });\n }\n\n private async takeScreenShot(elem: puppeteer.ElementHandle): Promise {\n const screenshotBuffer = await elem.screenshot({\n encoding: 'binary',\n omitBackground: true,\n });\n return PNG.sync.read(Buffer.from(screenshotBuffer));\n }\n}","export class Timecode {\n public readonly hours: number;\n public readonly minutes: number;\n public readonly seconds: number;\n public readonly millis: number;\n\n constructor(millis: number) {\n this.millis = millis % 1000;\n\n this.hours = Math.floor(millis / 3_600_000);\n const remainingMillisAfterHours = millis % 3_600_000;\n this.minutes = Math.floor(remainingMillisAfterHours / 60_000);\n const remainingMillisAfterMinutes = remainingMillisAfterHours % 60_000;\n this.seconds = Math.floor(remainingMillisAfterMinutes / 1000);\n }\n\n public get hh(): string {\n return String(this.hours).padStart(2, '0');\n }\n\n public get mm(): string {\n return String(this.minutes).padStart(2, '0');\n }\n\n public get ss(): string {\n return String(this.seconds).padStart(2, '0');\n }\n public get SSS(): string {\n return String(this.millis).padStart(3, '0');\n }\n\n public get asString(): string {\n return `${this.hh}:${this.mm}:${this.ss},${this.SSS}`;\n }\n}\n\nexport function toMillis(timecodes: string): number {\n const parts = timecodes.split(/[:,]/).map(Number);\n\n const hours = parts[0];\n const minutes = parts[1];\n const seconds = parts[2];\n const milliseconds = parts[3];\n\n return hours * 3_600_000 // hours to millis\n + minutes * 60_000 // minutes to millis\n + seconds * 1000 // second to millis\n + milliseconds;\n}","import {toMillis} from './timecodes';\n\nconst indexLinePattern = /^\\d+$/;\nconst timecodesLinePattern = /^(\\d{2}:\\d{2}:\\d{2},\\d{3}) --> (\\d{2}:\\d{2}:\\d{2},\\d{3})$/;\nconst highlightedWordPattern = /^\\[(.+)](?:\\((\\w+)\\))?$/;\n\nexport interface Word {\n rawWord: string;\n isHighlighted: boolean;\n isBeforeHighlighted: boolean;\n isAfterHighlighted: boolean;\n highlightClass?: string;\n}\n\nexport interface Caption {\n index: number;\n startTimeMs: number;\n endTimeMs: number;\n words: Word[];\n}\n\nexport function haveSameWords(caption1: Caption, caption2: Caption): boolean {\n if (caption1.words.length != caption2.words.length) {\n return false;\n }\n\n for (let i =0; i < caption1.words.length; i++) {\n if (caption1.words[i].rawWord != caption2.words[i].rawWord) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function readCaptions(srtContent: string): Caption[] {\n const lines = srtContent.split('\\n');\n const captions: Caption[] = [];\n\n let index: number = 0;\n let timecodesStart: string | null = null;\n let timecodesEnd: string | null = null;\n\n for (const line of lines) {\n let match;\n if ((match = line.match(indexLinePattern))) {\n index = Number(line);\n } else if ((match = line.match(timecodesLinePattern))) {\n timecodesStart = match[1];\n timecodesEnd = match[2];\n } else if (line.length) {\n const start = toMillis(timecodesStart!);\n const end = toMillis(timecodesEnd!);\n\n const words = readWords(line);\n\n captions.push({\n index,\n words,\n startTimeMs: start,\n endTimeMs: end,\n });\n }\n }\n\n return captions;\n}\n\nexport function readWords(text: string): Word[] {\n const words = splitText(text);\n const highlightedIndex = words.findIndex(word => word.match(highlightedWordPattern));\n\n const res: Word[] = [];\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const match = word.match(highlightedWordPattern);\n const rawWord = match ? match[1] : word;\n const highlightClass = match && match[2] ? match[2] : null;\n\n const isHighlighted = Boolean(match);\n const isBeforeHighlighted = Boolean(~highlightedIndex && !isHighlighted && i < highlightedIndex);\n const isAfterHighlighted = Boolean(~highlightedIndex && !isHighlighted && i > highlightedIndex);\n\n const wordObject: Word = {\n rawWord,\n isHighlighted,\n isBeforeHighlighted,\n isAfterHighlighted,\n };\n\n if (highlightClass) {\n wordObject.highlightClass = highlightClass;\n }\n\n res.push(wordObject);\n }\n\n return res;\n}\n\nexport function splitText(text: string): string[] {\n const words: string[] = [];\n\n let currentWord = '';\n let isCurrentHighlighted = false;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const isWhitespace = /^\\s$/.test(char);\n const isPunctuation = /[,.!?]/.test(char);\n\n if (!isWhitespace) {\n if (!isPunctuation) {\n currentWord += char;\n switch (char) {\n case '[':\n case '(':\n isCurrentHighlighted = true;\n break;\n case ']':\n case ')':\n isCurrentHighlighted = false;\n break;\n }\n } else {\n if (currentWord) {\n currentWord += char;\n } else {\n // Attach punctuation mark to the previous word\n words[words.length - 1] += ' ' + char;\n }\n }\n } else {\n // char is a whitespace\n if (isCurrentHighlighted) {\n currentWord += char;\n } else if (currentWord) {\n words.push(currentWord);\n currentWord = '';\n }\n }\n }\n\n if (currentWord) {\n words.push(currentWord);\n }\n\n return words;\n}","import {createServer} from 'http-server';\n\nexport class WebServer {\n constructor(private readonly rootDir: string) {\n }\n\n public async start(relativePath = '') {\n return new Promise(async (resolve, reject) => {\n try {\n const server = createServer({ root: this.rootDir });\n const port = await WebServer.getFreePort();\n\n server.listen(port, async () => {\n try {\n const childProcess = await WebServer.openUrl(`http://127.0.0.1:${port}${relativePath}`);\n\n childProcess.on('close', () => {\n server.close(() => {\n resolve();\n });\n });\n } catch (error) {\n reject(error);\n }\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n private static async getFreePort(): Promise {\n const { default: getPort } = await import('get-port');\n return getPort();\n }\n\n private static async openUrl(url: string) {\n const { default: open } = await import('open');\n return open(url, { wait: true });\n }\n}","import {readFileSync} from 'fs';\nimport {Args, createProgressBar, parseArgs, printArgs} from './cli';\nimport {WorkDir} from './work-dir';\nimport {StepRenderer} from './step-renderer';\nimport {RealTimeRecorder} from './real-time-recorder';\nimport {RealTimeRenderer} from './real-time-renderer';\nimport {StepRecorder} from './step-recorder';\nimport {AbstractRecorder} from './abstract-recorder';\nimport {Caption, readCaptions} from '../common/captions';\nimport {WebServer} from '../common/web-server';\n\nfunction parseCaptions(srtCaptionsFile: string): Caption[] {\n const captionsSrc = readFileSync(srtCaptionsFile, 'utf-8');\n return readCaptions(captionsSrc);\n}\n\nfunction createRecorder(args: Args, captions: Caption[], workDir: WorkDir): AbstractRecorder {\n if (args.css3Animations) {\n const realTimeRenderer = new RealTimeRenderer(args);\n return new RealTimeRecorder(args, realTimeRenderer);\n } else {\n const progressBar = createProgressBar();\n const stepRenderer = new StepRenderer(args, workDir);\n return new StepRecorder(args, captions, stepRenderer, progressBar);\n }\n}\n\nconst cliArgs = parseArgs();\nconst captions = parseCaptions(cliArgs.srtInputFile);\nconst workDir = new WorkDir(captions, cliArgs);\n\n(async () => {\n try {\n const indexHtml = workDir.setup();\n printArgs(cliArgs);\n\n if (!cliArgs.isPreview) {\n const recorder = createRecorder(cliArgs, captions, workDir);\n await recorder.recordCaptionsVideo(indexHtml);\n } else {\n console.log('Launching preview server...');\n const previewServer = new WebServer(workDir.rootDir);\n await previewServer.start();\n }\n console.log('Done!');\n } catch (err) {\n console.error('Error occurred:', err);\n } finally {\n workDir.clear();\n }\n})();\n"],"names":["program","path","cliProgress","tmp","symlinkSync","mkdirSync","rmSync","writeFileSync","setFfmpegPath","PNG","appendFileSync","puppeteer","PassThrough","createServer","readFileSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,MAAM,SAAS,GAAG,UAAoB;;EAEtC,OAAO,GAAG,iBAAiB,EAAE;;AAE7B;AACA;AACA,EAAA,OAAA,CAAA,OAAA,GAAkB,IAAI,SAAS,CAAC,OAAO,EAAE;;AAEzC;AACA;AACA;;EAEA,OAAmB,CAAA,QAAA,GAAA,SAAS,CAAC,QAAQ;EACrC,OAAkB,CAAA,OAAA,GAAA,SAAS,CAAC,OAAO;EACnC,OAAyB,CAAA,cAAA,GAAA,SAAS,CAAC,cAAc;EACjD,OAAe,CAAA,IAAA,GAAA,SAAS,CAAC,IAAI;EAC7B,OAA+B,CAAA,oBAAA,GAAA,SAAS,CAAC,oBAAoB;EAC7D,OAAqC,CAAA,0BAAA,GAAA,SAAS,CAAC,oBAAoB,CAAC;EACpE,OAAiB,CAAA,MAAA,GAAA,SAAS,CAAC,MAAM;;AAEjC;AACA;AACA;EACA,OAAwB,CAAA,aAAA,GAAA,CAAC,IAAI,KAAK,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;EAC7D,OAAuB,CAAA,YAAA,GAAA,CAAC,KAAK,EAAE,WAAW;IACxC,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC;EAC1C,OAAyB,CAAA,cAAA,GAAA,CAAC,IAAI,EAAE,WAAW;IACzC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;;;;;;;;ACzB3C;AACO,MAAM;AACb,WAAEA,SAAO;AACT,EAAE,aAAa;AACf,EAAE,cAAc;AAChB,EAAE,YAAY;AACd,EAAE,cAAc;AAChB,EAAE,oBAAoB;AACtB,EAAE,0BAA0B;AAC5B,EAAE,OAAO;AACT,EAAE,QAAQ;AACV,EAAE,MAAM;AACR,EAAE,IAAI;AACN,CAAC,GAAG,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACblB,MAAM,YAAY,GAAGC,eAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC;AAC/D,MAAM,gBAAgB,GAAGA,eAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;AAChE,MAAM,SAAS,GAAGA,eAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;AAEvD,MAAM,OAAO,GAAGA,eAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC;AAE7D,MAAM,WAAW,GAAGA,eAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;;ACS3E,SAAS,iBAAiB,CAAC,GAAG,UAAmC,EAAA;IAC7D,OAAO,CAAC,KAAa,KAAI;QACrB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;AAC/B,QAAA,UAAU,CAAC,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;AAC/C,QAAA,OAAO,GAAG;AACd,KAAC;AACL;AAEA,SAAS,cAAc,CAAC,MAAc,EAAA;IAClC,OAAO,CAAC,KAAa,KAAI;AACrB,QAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACX,YAAA,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAA,oBAAA,CAAsB,CAAC;;AAExD,KAAC;AACL;AAEA,SAAS,YAAY,CAAC,MAAc,EAAE,GAAW,EAAE,GAAW,EAAA;IAC1D,OAAO,CAAC,KAAa,KAAI;QACrB,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,CAAG,EAAA,MAAM,CAAsB,mBAAA,EAAA,GAAG,CAAQ,KAAA,EAAA,GAAG,CAAG,CAAA,CAAA,CAAC;;AAEzE,KAAC;AACL;AAEA,SAAS,mBAAmB,CAAC,GAAW,EAAA;IACpC,OAAO,CAAC,KAAa,KAAI;QACrB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACtB,YAAA,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,CAAA,CAAA,CAAG,CAAC;;AAEzD,QAAA,OAAO,KAAK;AAChB,KAAC;AACL;AAEA,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;AAE7B;KACK,IAAI,CAAC,SAAS;KACd,WAAW,CAAC,6CAA6C;AACzD,KAAA,OAAO,CAAC,WAAW,CAAC,OAAO;KAC3B,QAAQ,CAAC,QAAQ,EAAE,gDAAgD,EAAE,mBAAmB,CAAC,MAAM,CAAC;KAChG,MAAM,CAAC,qBAAqB,EACzB,8FAA8F;AAC9F,IAAA,gFAAgF,EAChF,mBAAmB,CAAC,MAAM,CAAC;AAC9B,KAAA,MAAM,CAAC,sBAAsB,EAC1B,+BAA+B,EAC/B,iBAAiB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,EAC1C,IAAI;AACP,KAAA,MAAM,CAAC,uBAAuB,EAC3B,gCAAgC,EAChC,iBAAiB,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EAC3C,IAAI;AACP,KAAA,MAAM,CAAC,oBAAoB,EACxB,wFAAwF,EACxF,iBAAiB,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAC7C,EAAE;KACL,MAAM,CAAC,oBAAoB,EACxB,iDAAiD;AACjD,IAAA,4DAA4D,EAC5D,mBAAmB,CAAC,MAAM,CAAC;KAC9B,MAAM,CAAC,eAAe,EACnB,yCAAyC;IACzC,qEAAqE;AACrE,IAAA,gEAAgE;KACnE,MAAM,CAAC,WAAW,EACf,oDAAoD;AACpD,IAAA,oFAAoF;AACvF,KAAA,MAAM,CAAC,CAAC,SAAS,EAAE,OAAY,KAAI;AAChC,IAAA,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACjB,MAAM,YAAY,GAAI,SAA2B,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9D,QAAA,OAAO,CAAC,MAAM,GAAG,CAAG,EAAA,YAAY,MAAM;;AAG1C,IAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;AAChB,QAAA,OAAO,CAAC,KAAK,GAAG,gBAAgB;;SAC7B;QACH,OAAO,CAAC,KAAK,GAAGA,eAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;;AAEnD,CAAC,CAAC;SAEU,SAAS,GAAA;IACrB,OAAO,CAAC,KAAK,EAAE;AACf,IAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAS;IAElC,OAAO;AACH,QAAA,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7B,aAAa,EAAE,IAAI,CAAC,MAAM;QAC1B,UAAU,EAAE,IAAI,CAAC,KAAK;QACtB,WAAW,EAAE,IAAI,CAAC,MAAM;QACxB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,KAAK;QACrB,cAAc,EAAE,IAAI,CAAC,OAAO;QAC5B,SAAS,EAAE,IAAI,CAAC,OAAO;KAC1B;AACL;AAEM,SAAU,SAAS,CAAC,IAAU,EAAA;AAChC,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,KAAK;AAC9B,UAAE;AACF,UAAE,IAAI,CAAC,SAAS;AAEpB,IAAA,MAAM,GAAG,GAAG;AACE,gBAAA,EAAA,IAAI,CAAC,aAAa;AAClB,gBAAA,EAAA,IAAI,CAAC,UAAU,CAAA;AACf,gBAAA,EAAA,IAAI,CAAC,WAAW,CAAA;AAChB,gBAAA,EAAA,IAAI,CAAC,GAAG;kBACR,MAAM;kBACL,IAAI,CAAC,cAAc,GAAG,KAAK,GAAG,IAAK;KACjD;AAED,IAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AACpB;SAEgB,iBAAiB,GAAA;AAC7B,IAAA,OAAO,IAAIC,sBAAW,CAAC,SAAS,CAAC;AAC7B,QAAA,MAAM,EAAE,4DAA4D;AACpE,QAAA,eAAe,EAAE,QAAQ;AACzB,QAAA,iBAAiB,EAAE,QAAQ;AAC3B,QAAA,UAAU,EAAE,IAAI;AACnB,KAAA,EAAEA,sBAAW,CAAC,OAAO,CAAC,cAAc,CAAC;AAC1C;;MCjIa,OAAO,CAAA;AAGa,IAAA,QAAA;AACA,IAAA,IAAA;IAHZ,OAAO,GAAGC,cAAG,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAEtE,WAA6B,CAAA,QAAmB,EACnB,IAAU,EAAA;QADV,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAI,CAAA,IAAA,GAAJ,IAAI;;IAG1B,KAAK,GAAA;AACR,QAAA,MAAM,KAAK,GAAGF,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC;AAExD,QAAAG,cAAW,CAAC,SAAS,EAAE,KAAK,CAAC;AAC7B,QAAAA,cAAW,CAAC,OAAO,EAAEH,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC9DG,cAAW,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAEH,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAC9E,QAAAG,cAAW,CAAC,WAAW,EAAEH,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAEtE,IAAI,CAAC,aAAa,EAAE;QACpB,IAAI,CAAC,eAAe,EAAE;QACtB,IAAI,CAAC,iBAAiB,EAAE;AAExB,QAAAI,YAAS,CAAC,IAAI,CAAC,cAAc,CAAC;AAE9B,QAAA,OAAO,KAAK;;IAGT,KAAK,GAAA;AACR,QAAAC,SAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;;AAG/D,IAAA,IAAW,cAAc,GAAA;AACrB,QAAA,OAAOL,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC;;AAGtD,IAAA,IAAW,OAAO,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI;;IAGpB,iBAAiB,GAAA;AACrB,QAAA,MAAM,GAAG,GAAE,CAAA;qBACE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA;sBACnB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA;UACjC;AACF,QAAA,MAAM,aAAa,GAAGA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC;AAEpE,QAAAM,gBAAa,CAAC,aAAa,EAAE,GAAG,CAAC;;IAG7B,aAAa,GAAA;AACjB,QAAA,MAAM,UAAU,GAAG,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAChF,QAAA,MAAM,cAAc,GAAGN,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC;AAElE,QAAAM,gBAAa,CAAC,cAAc,EAAE,UAAU,CAAC;;IAGrC,eAAe,GAAA;AACnB,QAAA,MAAM,UAAU,GAAe;AAC3B,YAAA,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS;SACjC;AACD,QAAA,MAAM,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3E,QAAA,MAAM,UAAU,GAAGN,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC;AAEjE,QAAAM,gBAAa,CAAC,UAAU,EAAE,MAAM,CAAC;;AAExC;;MCtEY,YAAY,CAAA;IACb,YAAY,GAAG,KAAK;AAErB,IAAA,KAAK,CAAC,KAAa,EAAA;QACtB,MAAM,KAAK,GAAG;aACT,OAAO,CAAC,KAAK;AACb,aAAA,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,GAAG,GAAG,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAC;AAE9C,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACnB,YAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,KAAA,EAAQ,KAAK,CAAC,MAAM,CAAA,CAAA,CAAG,CAAC,CAAC;;AAGlD,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACnB,YAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,EAAA,CAAI,CAAC,CAAC;AACnD,SAAC,CAAC;AAEF,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI;;AAE/B;;ACfD,CAAC,MAAK;AACF,IAAA,IAAI;AACA,QAAA,MAAM,eAAe,GAAG,OAAO,CAAC,0BAA0B,CAAC;AAC3D,QAAAC,oBAAa,CAAC,eAAgB,CAAC,IAAI,CAAC;;IACtC,OAAO,KAAK,EAAE;AACZ,QAAA,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC;;AAEjF,CAAC,GAAG;MAEkB,gBAAgB,CAAA;AACO,IAAA,IAAA;AAAzC,IAAA,WAAA,CAAyC,IAAW,EAAA;QAAX,IAAI,CAAA,IAAA,GAAJ,IAAI;;IAMnC,iBAAiB,GAAA;AACvB,QAAA,OAAO,MAAM;AACR,aAAA,aAAa,CAAC;AACX,YAAA,gBAAgB;AAChB,YAAA,iBAAiB;AACjB,YAAA,uBAAuB;AACvB,YAAA,QAAQ;AACR,YAAA,cAAc;SACjB;AACA,aAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;;AAE3C;;ACrBK,MAAO,YAAa,SAAQ,gBAAgB,CAAA;AAKjB,IAAA,OAAA;AAJZ,IAAA,cAAc;AACd,IAAA,kBAAkB;IAEnC,WAAY,CAAA,IAAW,EACM,OAAgB,EAAA;QACzC,KAAK,CAAC,IAAI,CAAC;QADc,IAAO,CAAA,OAAA,GAAP,OAAO;AAEhC,QAAA,IAAI,CAAC,cAAc,GAAGP,eAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC;AACrE,QAAA,IAAI,CAAC,kBAAkB,GAAGA,eAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC;;IAGrE,aAAa,GAAA;AAChB,QAAA,MAAM,KAAK,GAAG,IAAIQ,SAAG,CAAC;AAClB,YAAA,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;AAC3B,YAAA,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;AAC7B,YAAA,SAAS,EAAE,CAAC;AACf,SAAA,CAAC;AACF,QAAAF,gBAAa,CAAC,IAAI,CAAC,kBAAkB,EAAEE,SAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;;AAG1D,IAAA,aAAa,CAAC,UAAmB,EAAA;AACpC,QAAA,IAAI,QAAQ,GAAG,CAAA,MAAA,EAAS,IAAI,CAAC,kBAAkB,KAAK;QAEpD,IAAI,UAAU,EAAE;AACZ,YAAA,MAAM,WAAW,GAAG,UAAU,GAAG,IAAI;AACrC,YAAA,QAAQ,IAAI,CAAA,SAAA,EAAY,WAAW,CAAA,EAAA,CAAI;;QAG3CC,iBAAc,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,CAAC;;IAGlD,QAAQ,CAAC,OAAgB,EAAE,GAAoB,EAAA;AAClD,QAAA,MAAM,kBAAkB,GAAGT,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAc,WAAA,EAAA,OAAO,CAAC,KAAK,CAAA,IAAA,CAAM,CAAC;AACpG,QAAAM,gBAAa,CAAC,kBAAkB,EAAEE,SAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEtD,QAAA,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI;AAEpE,QAAAC,iBAAc,CACV,IAAI,CAAC,cAAc,EACnB,CAAA,MAAA,EAAS,kBAAkB,CAAA,YAAA,EAAe,WAAW,CAAA,EAAA,CAAI,EACzD,MAAM,CAAC;;AAGR,IAAA,MAAM,WAAW,GAAA;QACpB,OAAO,CAAC,GAAG,CAAC,CAAY,SAAA,EAAA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAO,KAAA,CAAA,CAAC;AACvD,QAAA,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE;QAEvC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YAClC,IAAI,CAAC,iBAAiB;AACjB,iBAAA,KAAK,CAAC,IAAI,CAAC,cAAc;AACzB,iBAAA,YAAY,CAAC;AACV,gBAAA,WAAW;AACX,gBAAA,SAAS;aACZ;AACA,iBAAA,EAAE,CAAC,UAAU,EAAE,CAAC,QAAgB,KAAI;AACjC,gBAAA,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;AAChC,aAAC;AACA,iBAAA,EAAE,CAAC,KAAK,EAAE,MAAK;gBACZ,OAAO,CAAC,GAAG,CAAC,CAAG,EAAA,IAAI,CAAC,IAAI,CAAC,aAAa,CAAU,QAAA,CAAA,CAAC;AACjD,gBAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;AACpC,aAAC;AACA,iBAAA,EAAE,CAAC,OAAO,EAAE,CAAC,GAAQ,KAAI;gBACtB,MAAM,CAAC,GAAG,CAAC;AACf,aAAC;AACA,iBAAA,GAAG,EAAE;AACd,SAAC,CAAC;;AAET;;MCzEqB,gBAAgB,CAAA;AAIO,IAAA,IAAA;IAH/B,OAAO,GAA6B,IAAI;IACxC,IAAI,GAA0B,IAAI;AAE5C,IAAA,WAAA,CAAyC,IAAU,EAAA;QAAV,IAAI,CAAA,IAAA,GAAJ,IAAI;;IAKnC,MAAM,aAAa,CAAC,SAAiB,EAAA;AAC3C,QAAA,IAAI,CAAC,OAAO,GAAG,MAAMC,oBAAS,CAAC,MAAM,CAAC;AAClC,YAAA,IAAI,EAAE;AACF,gBAAA,wBAAwB;AACxB,gBAAA,gCAAgC;AACnC,aAAA;AACD,YAAA,QAAQ,EAAE,IAAI;AACjB,SAAA,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;QACxC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAU,OAAA,EAAA,SAAS,CAAE,CAAA,CAAC;AAC3C,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;AACxB,YAAA,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;AAC3B,YAAA,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;AAChC,SAAA,CAAC;AACF,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAK;YAC1B,OAAO,MAAM,CAAC,KAAK;AACvB,SAAC,CAAC;QAEF,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;;AAEnC;;AC3BK,MAAO,gBAAiB,SAAQ,gBAAgB,CAAA;AAErB,IAAA,aAAA;IAD7B,WAAY,CAAA,IAAU,EACO,aAA+B,EAAA;QACxD,KAAK,CAAC,IAAI,CAAC;QADc,IAAa,CAAA,aAAA,GAAb,aAAa;;IAInC,MAAM,mBAAmB,CAAC,SAAiB,EAAA;AAC9C,QAAA,IAAI;AACA,YAAA,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAK,CAAC,gBAAgB,EAAE;AAEtD,YAAA,MAAM,UAAU,CAAC,IAAI,CACjB,6CAA6C,EAC7C,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CACxC;AACD,YAAA,MAAM,UAAU,CAAC,IAAI,CAAC,2BAA2B,EAAE;AAC/C,gBAAA,YAAY,EAAE,CAAC;AAClB,aAAA,CAAC;AAEF,YAAA,UAAU,CAAC,EAAE,CAAC,sBAAsB,EAChC,CAAC,KAAK,KAAK,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAE7D,YAAA,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE;AAElC,YAAA,MAAM,UAAU,CAAC,IAAI,CAAC,sBAAsB,EAAE;AAC1C,gBAAA,aAAa,EAAE,CAAC;AAChB,gBAAA,MAAM,EAAE,KAAK;AACb,gBAAA,OAAO,EAAE,GAAG;AACf,aAAA,CAAC;AAEF,YAAA,MAAM,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC,MAAK;AAC3B,gBAAA,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,KAAI;AACjC,oBAAA,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO;AAC9B,oBAAA,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;AACxB,iBAAC,CAAC;AACN,aAAC,CAAC;AAEF,YAAA,MAAM,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC;AAE5C,YAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE;;QAClC,OAAO,KAAK,EAAE;AACZ,YAAA,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC;;gBACnD;AACN,YAAA,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE;;;AAI3B,IAAA,MAAM,qBAAqB,CAAC,UAAgC,EAChC,KAAmD,EAAA;AACnF,QAAA,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,KAAK;QACjC,MAAM,UAAU,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,SAAS,EAAE,CAAC;QAC/D,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;AAC/C,QAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC;;AAE/C;;ACrDK,MAAO,gBAAiB,SAAQ,gBAAgB,CAAA;IAC1C,WAAW,GAAuB,IAAI;IACtC,UAAU,GAA0B,IAAI;AACxC,IAAA,SAAS;AAEjB,IAAA,WAAA,CAAY,IAAU,EAAA;QAClB,KAAK,CAAC,IAAI,CAAC;AACX,QAAA,MAAM,KAAK,GAAG,IAAIF,SAAG,CAAC;AAClB,YAAA,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;AAC3B,YAAA,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW;AAC7B,YAAA,SAAS,EAAE,CAAC;AACf,SAAA,CAAC;QACF,IAAI,CAAC,SAAS,GAAGA,SAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;;IAGnC,aAAa,GAAA;AAChB,QAAA,IAAI,CAAC,WAAW,GAAG,IAAIG,kBAAW,EAAE;AACpC,QAAA,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE;AAEvC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB;AACjC,aAAA,KAAK,CAAC,IAAI,CAAC,WAAW;AACtB,aAAA,YAAY,CAAC;AACV,YAAA,eAAe;AACf,YAAA,uBAAuB;AACvB,YAAA,CAAA,GAAA,EAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAA,CAAE;AACrD,YAAA,CAAA,GAAA,EAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAA,CAAE;SACxB;AACA,aAAA,EAAE,CAAC,OAAO,EAAE,MAAK;AACd,YAAA,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;AAC1C,SAAC;AACA,aAAA,EAAE,CAAC,UAAU,EAAE,CAAC,QAAQ,KAAI;AACzB,YAAA,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;AAChC,SAAC;AACA,aAAA,EAAE,CAAC,KAAK,EAAE,MAAK;AACZ,YAAA,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;AAC5C,SAAC;AACA,aAAA,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAI;YACjB,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,OAAO,CAAC;AACpD,SAAC,CAAC;QAEN,OAAO,CAAC,GAAG,EAAE;;QAGb,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;AAC9C,QAAA,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,MAAK;YAC/B,IAAI,CAAC,WAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1C,EAAE,gBAAgB,CAAC;;AAGjB,IAAA,QAAQ,CAAC,KAAa,EAAA;AACzB,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;;IAGnB,WAAW,GAAA;AACd,QAAA,YAAY,CAAC,IAAI,CAAC,UAAW,CAAC;AAC9B,QAAA,IAAI,CAAC,WAAY,CAAC,GAAG,EAAE;;AAE9B;;ACvDK,MAAO,YAAa,SAAQ,gBAAgB,CAAA;AAEjB,IAAA,QAAA;AACA,IAAA,QAAA;AACA,IAAA,WAAA;AAH7B,IAAA,WAAA,CAAY,IAAU,EACO,QAAmB,EACnB,QAAsB,EACtB,WAAkC,EAAA;QAC3D,KAAK,CAAC,IAAI,CAAC;QAHc,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAW,CAAA,WAAA,GAAX,WAAW;;IAIjC,MAAM,mBAAmB,CAAC,SAAiB,EAAA;AAC9C,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAE/C,QAAA,IAAI;YACA,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC;AAErD,YAAA,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;;YAG7B,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW;AAClD,YAAA,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC;AAE1C,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEhC,gBAAA,MAAM,IAAI,CAAC,QAAQ,EAAE;gBAErB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,SAAU,CAAC;gBACxD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;;gBAG3C,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;AAC9B,oBAAA,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,SAAS;oBACtE,IAAI,SAAS,EAAE;AACX,wBAAA,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;;;AAI9C,gBAAA,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;;;AAIhC,YAAA,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;AAE7B,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;AACvB,YAAA,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;;QACnC,OAAO,KAAK,EAAE;AACZ,YAAA,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC;;gBACnD;AACN,YAAA,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE;;;AAI3B,IAAA,MAAM,QAAQ,GAAA;AAClB,QAAA,MAAM,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC,MAAK;AAC3B,YAAA,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;AACxB,SAAC,CAAC;;IAGE,MAAM,cAAc,CAAC,IAA6B,EAAA;AACtD,QAAA,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;AAC3C,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,cAAc,EAAE,IAAI;AACvB,SAAA,CAAC;AACF,QAAA,OAAOH,SAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;;AAE1D;;ACpCK,SAAU,QAAQ,CAAC,SAAiB,EAAA;AACtC,IAAA,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AAEjD,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;AACtB,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;AACxB,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;AACxB,IAAA,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC;AAE7B,IAAA,OAAO,KAAK,GAAG,SAAS;UAClB,OAAO,GAAG,MAAM;UAChB,OAAO,GAAG,IAAI;AACd,UAAA,YAAY;AACtB;;AC9CA,MAAM,gBAAgB,GAAG,OAAO;AAChC,MAAM,oBAAoB,GAAG,2DAA2D;AACxF,MAAM,sBAAsB,GAAG,yBAAyB;AA+BlD,SAAU,YAAY,CAAC,UAAkB,EAAA;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;IACpC,MAAM,QAAQ,GAAc,EAAE;IAE9B,IAAI,KAAK,GAAW,CAAC;IACrB,IAAI,cAAc,GAAkB,IAAI;IACxC,IAAI,YAAY,GAAkB,IAAI;AAEtC,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACtB,QAAA,IAAI,KAAK;QACT,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG;AACxC,YAAA,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;;aACjB,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG;AACnD,YAAA,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC;AACzB,YAAA,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC;;AACpB,aAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACpB,YAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAe,CAAC;AACvC,YAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAa,CAAC;AAEnC,YAAA,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;YAE7B,QAAQ,CAAC,IAAI,CAAC;gBACV,KAAK;gBACL,KAAK;AACL,gBAAA,WAAW,EAAE,KAAK;AAClB,gBAAA,SAAS,EAAE,GAAG;AACjB,aAAA,CAAC;;;AAIV,IAAA,OAAO,QAAQ;AACnB;AAEM,SAAU,SAAS,CAAC,IAAY,EAAA;AAClC,IAAA,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;AAC7B,IAAA,MAAM,gBAAgB,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAEpF,MAAM,GAAG,GAAW,EAAE;AAEtB,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACnC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC;AAChD,QAAA,MAAM,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;AACvC,QAAA,MAAM,cAAc,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;AAE1D,QAAA,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC;AACpC,QAAA,MAAM,mBAAmB,GAAG,OAAO,CAAC,CAAC,gBAAgB,IAAI,CAAC,aAAa,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAChG,QAAA,MAAM,kBAAkB,GAAG,OAAO,CAAC,CAAC,gBAAgB,IAAI,CAAC,aAAa,IAAI,CAAC,GAAG,gBAAgB,CAAC;AAE/F,QAAA,MAAM,UAAU,GAAS;YACrB,OAAO;YACP,aAAa;YACb,mBAAmB;YACnB,kBAAkB;SACrB;QAED,IAAI,cAAc,EAAE;AAChB,YAAA,UAAU,CAAC,cAAc,GAAG,cAAc;;AAG9C,QAAA,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;;AAGxB,IAAA,OAAO,GAAG;AACd;AAEM,SAAU,SAAS,CAAC,IAAY,EAAA;IAClC,MAAM,KAAK,GAAa,EAAE;IAE1B,IAAI,WAAW,GAAG,EAAE;IACpB,IAAI,oBAAoB,GAAG,KAAK;AAEhC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;QACpB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAEzC,IAAI,CAAC,YAAY,EAAE;YACf,IAAI,CAAC,aAAa,EAAE;gBAChB,WAAW,IAAI,IAAI;gBACnB,QAAQ,IAAI;AACR,oBAAA,KAAK,GAAG;AACR,oBAAA,KAAK,GAAG;wBACJ,oBAAoB,GAAG,IAAI;wBAC3B;AACJ,oBAAA,KAAK,GAAG;AACR,oBAAA,KAAK,GAAG;wBACJ,oBAAoB,GAAG,KAAK;wBAC5B;;;iBAEL;gBACH,IAAI,WAAW,EAAE;oBACb,WAAW,IAAI,IAAI;;qBAChB;;oBAEH,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI;;;;aAG1C;;YAEH,IAAI,oBAAoB,EAAE;gBACtB,WAAW,IAAI,IAAI;;iBAChB,IAAI,WAAW,EAAE;AACpB,gBAAA,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;gBACvB,WAAW,GAAG,EAAE;;;;IAK5B,IAAI,WAAW,EAAE;AACb,QAAA,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;;AAG3B,IAAA,OAAO,KAAK;AAChB;;MCnJa,SAAS,CAAA;AACW,IAAA,OAAA;AAA7B,IAAA,WAAA,CAA6B,OAAe,EAAA;QAAf,IAAO,CAAA,OAAA,GAAP,OAAO;;AAG7B,IAAA,MAAM,KAAK,CAAC,YAAY,GAAG,EAAE,EAAA;QAChC,OAAO,IAAI,OAAO,CAAO,OAAO,OAAO,EAAE,MAAM,KAAI;AAC/C,YAAA,IAAI;AACA,gBAAA,MAAM,MAAM,GAAGI,uBAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;AACnD,gBAAA,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE;AAE1C,gBAAA,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAW;AAC3B,oBAAA,IAAI;AACA,wBAAA,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA,iBAAA,EAAoB,IAAI,CAAA,EAAG,YAAY,CAAA,CAAE,CAAC;AAEvF,wBAAA,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;AAC1B,4BAAA,MAAM,CAAC,KAAK,CAAC,MAAK;AACd,gCAAA,OAAO,EAAE;AACb,6BAAC,CAAC;AACN,yBAAC,CAAC;;oBACJ,OAAO,KAAK,EAAE;wBACZ,MAAM,CAAC,KAAK,CAAC;;AAErB,iBAAC,CAAC;;YACJ,OAAO,KAAK,EAAE;gBACZ,MAAM,CAAC,KAAK,CAAC;;AAErB,SAAC,CAAC;;IAGE,aAAa,WAAW,GAAA;QAC5B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,UAAU,CAAC;QACrD,OAAO,OAAO,EAAE;;AAGZ,IAAA,aAAa,OAAO,CAAC,GAAW,EAAA;QACpC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,MAAM,CAAC;QAC9C,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;AAEvC;;AC7BD,SAAS,aAAa,CAAC,eAAuB,EAAA;IAC1C,MAAM,WAAW,GAAGC,eAAY,CAAC,eAAe,EAAE,OAAO,CAAC;AAC1D,IAAA,OAAO,YAAY,CAAC,WAAW,CAAC;AACpC;AAEA,SAAS,cAAc,CAAC,IAAU,EAAE,QAAmB,EAAE,OAAgB,EAAA;AACrE,IAAA,IAAI,IAAI,CAAC,cAAc,EAAE;AACrB,QAAA,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC;AACnD,QAAA,OAAO,IAAI,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,CAAC;;SAChD;AACH,QAAA,MAAM,WAAW,GAAG,iBAAiB,EAAE;QACvC,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC;QACpD,OAAQ,IAAI,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC;;AAE3E;AAEA,MAAM,OAAO,GAAG,SAAS,EAAE;AAC3B,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC;AACpD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;AAE9C,CAAC,YAAW;AACR,IAAA,IAAI;AACA,QAAA,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE;QACjC,SAAS,CAAC,OAAO,CAAC;AAElB,QAAA,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;YACpB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC;AAC3D,YAAA,MAAM,QAAQ,CAAC,mBAAmB,CAAC,SAAS,CAAC;;aAC1C;AACH,YAAA,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;YAC1C,MAAM,aAAa,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;AACpD,YAAA,MAAM,aAAa,CAAC,KAAK,EAAE;;AAE/B,QAAA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;;IACtB,OAAO,GAAG,EAAE;AACV,QAAA,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,GAAG,CAAC;;YAC/B;QACN,OAAO,CAAC,KAAK,EAAE;;AAEvB,CAAC,GAAG;;","x_google_ignoreList":[0,1]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../node_modules/@commander-js/extra-typings/index.js","../../node_modules/@commander-js/extra-typings/esm.mjs","../../src/script/assets.ts","../../src/script/cli.ts","../../src/script/work-dir.ts","../../src/script/stats-printer.ts","../../src/script/abstract-renderer.ts","../../src/script/step-renderer.ts","../../src/script/abstract-recorder.ts","../../src/script/real-time-recorder.ts","../../src/script/real-time-renderer.ts","../../src/script/step-recorder.ts","../../src/common/timecodes.ts","../../src/common/captions.ts","../../src/common/web-server.ts","../../src/script/index.ts"],"sourcesContent":["const commander = require('commander');\n\nexports = module.exports = {};\n\n// Return a different global program than commander,\n// and don't also return it as default export.\nexports.program = new commander.Command();\n\n/**\n * Expose classes. The FooT versions are just types, so return Commander original implementations!\n */\n\nexports.Argument = commander.Argument;\nexports.Command = commander.Command;\nexports.CommanderError = commander.CommanderError;\nexports.Help = commander.Help;\nexports.InvalidArgumentError = commander.InvalidArgumentError;\nexports.InvalidOptionArgumentError = commander.InvalidArgumentError; // Deprecated\nexports.Option = commander.Option;\n\n// In Commander, the create routines end up being aliases for the matching\n// methods on the global program due to the (deprecated) legacy default export.\n// Here we roll our own, the way Commander might in future.\nexports.createCommand = (name) => new commander.Command(name);\nexports.createOption = (flags, description) =>\n new commander.Option(flags, description);\nexports.createArgument = (name, description) =>\n new commander.Argument(name, description);\n","import extraTypingsCommander from './index.js';\n\n// wrapper to provide named exports for ESM.\nexport const {\n program,\n createCommand,\n createArgument,\n createOption,\n CommanderError,\n InvalidArgumentError,\n InvalidOptionArgumentError, // deprecated old name\n Command,\n Argument,\n Option,\n Help,\n} = extraTypingsCommander;\n","import * as path from 'path';\n\nexport const assetsFolder = path.join(__dirname, '..', '..', 'assets');\nexport const defaultStylesCss = path.join(assetsFolder, 'captions.css');\nexport const indexHtml = path.join(assetsFolder, 'index.html');\n\nexport const indexJs = path.join(__dirname, '..', 'player', 'index.js');\n\nexport const nodeModules = path.join(__dirname, '..', '..', 'node_modules');\n","import {Command} from '@commander-js/extra-typings';\nimport packageJson from '../../package.json';\nimport {defaultStylesCss} from './assets';\nimport * as cliProgress from 'cli-progress';\nimport * as path from 'path';\n\nexport interface Args {\n srtInputFile: string;\n movOutputFile: string;\n videoWidth: number;\n videoHeight: number;\n fps: number;\n styleFile: string;\n css3Animations: boolean;\n isPreview: boolean;\n}\n\nfunction parseIntAndAssert(...assertions: ((v: number) => void)[]): (v: string) => number {\n return (value: string) => {\n const int = parseInt(value, 10);\n assertions.forEach(assertion => assertion(int));\n return int;\n }\n}\n\nfunction assertPositive(option: string): (v: number) => void {\n return (value: number) => {\n if (value < 0) {\n throw new Error(`${option} should be positive!`);\n }\n };\n}\n\nfunction assertMinMax(option: string, min: number, max: number): (v: number) => void {\n return (value: number) => {\n if (value < min || value > max) {\n throw new Error(`${option} should be between ${min} and ${max}!`);\n }\n };\n}\n\nfunction assertFileExtension(ext: string): (v: string) => void {\n return (value: string) => {\n if (!value.endsWith(ext)) {\n throw new Error(`File should have extension ${ext}!`);\n }\n return value;\n };\n}\n\nconst program = new Command();\n\nprogram\n .name('pupcaps')\n .description('Tool to add stylish captions to your video.')\n .version(packageJson.version)\n .argument('', 'Path to the input SubRip Subtitle (.srt) file.', assertFileExtension('.srt'))\n .option('-o, --output ',\n 'Full or relative path where the created Films Apple QuickTime (MOV) file should be written. ' +\n 'By default, it will be saved in the same directory as the input subtitle file.',\n assertFileExtension('.mov'))\n .option('-w, --width ',\n 'Width of the video in pixels.',\n parseIntAndAssert(assertPositive('Width')),\n 1080)\n .option('-h, --height ',\n 'Height of the video in pixels.',\n parseIntAndAssert(assertPositive('Height')),\n 1920)\n .option('-r, --fps ',\n 'Specifies the frame rate (FPS) of the output video. Valid values are between 1 and 60.',\n parseIntAndAssert(assertMinMax('FPS', 1, 60)),\n 30)\n .option('-s, --style ',\n 'Full or relative path to the styles .css file. ' +\n 'If not provided, default styles for captions will be used.',\n assertFileExtension('.css'))\n .option('-a, --animate',\n 'Records captions with CSS3 animations. ' +\n 'Note: The recording will run for the entire duration of the video. ' +\n 'Use this option only if your captions involve CSS3 animations.')\n .option('--preview',\n 'Prevents the script from generating a video file. ' +\n 'Instead, captions are displayed in the browser for debugging and preview purposes.')\n .action((inputFile, options: any) => {\n if (!options.output) {\n const fileBasename = (inputFile as any as string).slice(0, -4);\n options.output = `${fileBasename}.mov`;\n }\n\n if (!options.style) {\n options.style = defaultStylesCss;\n } else {\n options.style = path.resolve(options.style);\n }\n });\n\nexport function parseArgs(): Args {\n program.parse();\n const opts = program.opts() as any;\n\n return {\n srtInputFile: program.args[0],\n movOutputFile: opts.output,\n videoWidth: opts.width,\n videoHeight: opts.height,\n fps: opts.fps,\n styleFile: opts.style,\n css3Animations: opts.animate,\n isPreview: opts.preview,\n };\n}\n\nexport function printArgs(args: Args) {\n const styles = args.styleFile === defaultStylesCss\n ? '(Default)'\n : args.styleFile;\n\n const srt = `\n Output: ${args.movOutputFile}\n Width: ${args.videoWidth} px\n Height: ${args.videoHeight} px\n FPS: ${args.fps}\n Styles: ${styles}\n Animations: ${ args.css3Animations ? 'yes' : 'no' }\n `;\n\n console.log(srt);\n}\n\nexport function createProgressBar(): cliProgress.SingleBar {\n return new cliProgress.SingleBar({\n format: 'Progress |{bar}| {percentage}% || {value}/{total} Captions',\n barCompleteChar: '\\u2588',\n barIncompleteChar: '\\u2591',\n hideCursor: true,\n }, cliProgress.Presets.shades_classic);\n}","import * as tmp from 'tmp';\nimport * as path from 'path';\nimport {writeFileSync, symlinkSync, rmSync, mkdirSync} from 'fs';\nimport {Caption} from '../common/captions';\nimport {Args} from './cli';\nimport {indexHtml, indexJs, nodeModules} from './assets';\nimport {PlayerArgs} from '../common/player-args';\n\nexport class WorkDir {\n private readonly workDir = tmp.dirSync({ template: 'pupcaps-XXXXXX' });\n\n constructor(private readonly captions: Caption[],\n private readonly args: Args) {\n }\n\n public setup(): string {\n const index = path.join(this.workDir.name, 'index.html');\n\n symlinkSync(indexHtml, index);\n symlinkSync(indexJs, path.join(this.workDir.name, 'index.js'));\n symlinkSync(this.args.styleFile, path.join(this.workDir.name, 'captions.css'));\n symlinkSync(nodeModules, path.join(this.workDir.name, 'node_modules'));\n\n this.setupCaptions();\n this.setupPlayerArgs();\n this.setupVideoSizeCss();\n\n mkdirSync(this.screenShotsDir);\n\n return index;\n }\n\n public clear() {\n rmSync(this.workDir.name, { recursive: true, force: true });\n }\n\n public get screenShotsDir(): string {\n return path.join(this.workDir.name, 'screenshots');\n }\n\n public get rootDir(): string {\n return this.workDir.name;\n }\n\n private setupVideoSizeCss() {\n const css= `#video {\n width: ${this.args.videoWidth}px;\n height: ${this.args.videoHeight}px;\n }`;\n const videoSizeFile = path.join(this.workDir.name, 'video.size.css');\n\n writeFileSync(videoSizeFile, css);\n }\n\n private setupCaptions() {\n const captionsJs = 'window.captions = ' + JSON.stringify(this.captions, null, 2);\n const captionsJsFile = path.join(this.workDir.name, 'captions.js');\n\n writeFileSync(captionsJsFile, captionsJs);\n }\n\n private setupPlayerArgs() {\n const playerArgs: PlayerArgs = {\n isPreview: this.args.isPreview,\n };\n const argsJs = 'window.playerArgs = ' + JSON.stringify(playerArgs, null, 2);\n const argsJsFile = path.join(this.workDir.name, 'player.args.js');\n\n writeFileSync(argsJsFile, argsJs);\n }\n}","export class StatsPrinter {\n private statsPrinted = false;\n\n public print(stats: Object) {\n const lines = Object\n .entries(stats)\n .map(([key, value]) => `${key}: ${value}`);\n\n if (this.statsPrinted) {\n process.stdout.write(`\\x1b[${lines.length}A`); // Move up N lines\n }\n\n lines.forEach((line) => {\n process.stdout.write(`\\r${line.padEnd(40)}\\n`); // Ensure the line is fully overwritten\n });\n\n this.statsPrinted = true;\n }\n}","import ffmpeg, { setFfmpegPath } from 'fluent-ffmpeg';\nimport {Args} from './cli';\n\n(() => {\n try {\n const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');\n setFfmpegPath(ffmpegInstaller!.path);\n } catch (error) {\n console.warn('Impossible to install FFMpeg. Use system-provided ffmpeg.');\n }\n})();\n\nexport abstract class AbstractRenderer {\n protected constructor(protected readonly args : Args) {\n }\n\n public abstract startEncoding(): void;\n public abstract endEncoding(): void;\n\n protected baseFfmpegCommand(): ffmpeg.FfmpegCommand {\n return ffmpeg()\n .outputOptions([\n '-c:v prores_ks', // codec for Films Apple QuickTime (MOV)\n '-profile:v 4444', // enable the best quality\n '-pix_fmt yuva444p10le', // lossless setting\n '-q:v 0', // lossless setting\n '-vendor ap10' // ensures the output MOV file is compatible with Apple QuickTime\n ])\n .output(this.args.movOutputFile);\n }\n}","import {Args} from './cli';\nimport {PNG, PNGWithMetadata} from 'pngjs';\nimport * as path from 'path';\nimport {appendFileSync, writeFileSync} from 'fs';\nimport {WorkDir} from './work-dir';\nimport {Caption} from '../common/captions';\nimport {StatsPrinter} from './stats-printer';\nimport {AbstractRenderer} from './abstract-renderer';\n\nexport class StepRenderer extends AbstractRenderer {\n private readonly framesFileName: string;\n private readonly emptyFrameFileName: string;\n\n constructor(args : Args,\n private readonly workDir: WorkDir) {\n super(args);\n this.framesFileName = path.join(workDir.screenShotsDir, 'frames.txt');\n this.emptyFrameFileName = path.join(workDir.screenShotsDir, 'empty.png');\n }\n\n public startEncoding() {\n const empty = new PNG({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n colorType: 6,\n });\n writeFileSync(this.emptyFrameFileName, PNG.sync.write(empty));\n }\n\n public addEmptyFrame(durationMs?: number) {\n let frameDef = `file '${this.emptyFrameFileName}'\\n`;\n\n if (durationMs) {\n const durationSec = durationMs / 1000;\n frameDef += `duration ${durationSec}\\n`;\n }\n\n appendFileSync(this.framesFileName, frameDef, 'utf8');\n }\n\n public addFrame(caption: Caption, png: PNGWithMetadata) {\n const screenShotFileName = path.join(this.workDir.screenShotsDir, `screenshot_${caption.index}.png`);\n writeFileSync(screenShotFileName, PNG.sync.write(png));\n\n const durationSec = (caption.endTimeMs - caption.startTimeMs) / 1000;\n\n appendFileSync(\n this.framesFileName,\n `file '${screenShotFileName}'\\nduration ${durationSec}\\n`,\n 'utf8');\n }\n\n public async endEncoding() {\n console.log(`Encoding ${this.args.movOutputFile}...\\n`);\n const statsPrinter = new StatsPrinter();\n\n await new Promise((resolve, reject) => {\n this.baseFfmpegCommand()\n .input(this.framesFileName)\n .inputOptions([\n '-f concat', // concat frames from the frame list\n '-safe 0' // to prevent errors related to unsafe filenames\n ])\n .on('progress', (progress: Object) => {\n statsPrinter.print(progress);\n })\n .on('end', () => {\n console.log(`${this.args.movOutputFile} encoded`);\n resolve(this.args.movOutputFile);\n })\n .on('error', (err: any) => {\n reject(err);\n })\n .run();\n });\n }\n}","import * as puppeteer from 'puppeteer';\nimport {Args} from './cli';\n\nexport abstract class AbstractRecorder {\n protected browser: puppeteer.Browser | null = null;\n protected page: puppeteer.Page | null = null;\n\n protected constructor(protected readonly args: Args) {\n }\n\n public abstract recordCaptionsVideo(indexHtml: string): Promise;\n\n protected async launchBrowser(indexHtml: string): Promise {\n this.browser = await puppeteer.launch({\n args: [\n '--disable-web-security', // Disable CORS\n '--allow-file-access-from-files', // Allow file access\n ],\n headless: true,\n });\n this.page = await this.browser.newPage();\n await this.page.goto(`file://${indexHtml}`);\n await this.page.setViewport({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n });\n await this.page.evaluate(() => {\n return window.ready;\n });\n\n return this.page.$('#video');\n }\n}","import * as puppeteer from 'puppeteer';\nimport {RealTimeRenderer} from './real-time-renderer';\nimport {Args} from './cli';\nimport {AbstractRecorder} from './abstract-recorder';\n\nexport class RealTimeRecorder extends AbstractRecorder {\n constructor(args: Args,\n private readonly videoRenderer: RealTimeRenderer) {\n super(args);\n }\n\n public async recordCaptionsVideo(indexHtml: string) {\n try {\n await this.launchBrowser(indexHtml);\n const cdpSession = await this.page!.createCDPSession();\n\n await cdpSession.send(\n 'Emulation.setDefaultBackgroundColorOverride',\n { color: { r: 0, g: 0, b: 0, a: 0 } }\n );\n await cdpSession.send('Animation.setPlaybackRate', {\n playbackRate: 1,\n });\n\n cdpSession.on('Page.screencastFrame',\n (frame) => this.handleScreenCastFrame(cdpSession, frame));\n\n this.videoRenderer.startEncoding();\n\n await cdpSession.send('Page.startScreencast', {\n everyNthFrame: 1,\n format: 'png',\n quality: 100,\n });\n\n await this.page!.evaluate(() => {\n return new Promise((resolve) => {\n window.Player.onStop = resolve;\n window.Player.play();\n })\n });\n\n await cdpSession.send('Page.stopScreencast');\n\n this.videoRenderer.endEncoding();\n } catch (error) {\n console.error('Error during Puppeteer operation:', error);\n } finally {\n await this.browser?.close();\n }\n }\n\n private async handleScreenCastFrame(cdpSession: puppeteer.CDPSession,\n frame: puppeteer.Protocol.Page.ScreencastFrameEvent) {\n const { sessionId, data } = frame;\n await cdpSession.send('Page.screencastFrameAck', { sessionId });\n const frameBuffer = Buffer.from(data, 'base64');\n this.videoRenderer.addFrame(frameBuffer);\n }\n}","import {PassThrough} from 'stream';\nimport {PNG} from 'pngjs';\nimport {Args} from './cli';\nimport {StatsPrinter} from './stats-printer';\nimport {AbstractRenderer} from './abstract-renderer';\n\nexport class RealTimeRenderer extends AbstractRenderer {\n private inputStream: PassThrough | null = null;\n private intervalId: NodeJS.Timeout | null = null;\n private lastFrame: Buffer;\n\n constructor(args: Args) {\n super(args);\n const empty = new PNG({\n width: this.args.videoWidth,\n height: this.args.videoHeight,\n colorType: 6,\n });\n this.lastFrame = PNG.sync.write(empty);\n }\n\n public startEncoding() {\n this.inputStream = new PassThrough();\n const statsPrinter = new StatsPrinter();\n\n const command = this.baseFfmpegCommand()\n .input(this.inputStream)\n .inputOptions([\n '-f image2pipe', // Format of input frames\n '-pix_fmt yuva444p10le', // Lossless setting\n `-s ${this.args.videoWidth}x${this.args.videoHeight}`, // Frame size\n `-r ${this.args.fps}`, // Framerate\n ])\n .on('start', () => {\n console.log('FFmpeg process started.');\n })\n .on('progress', (progress) => {\n statsPrinter.print(progress);\n })\n .on('end', () => {\n console.log('FFmpeg process completed.');\n })\n .on('error', (err) => {\n console.error('An error occurred:', err.message);\n });\n\n command.run();\n\n // Produce frames in required rate\n const intervalDuration = Math.round(1000 / 30);\n this.intervalId = setInterval(() => {\n this.inputStream!.write(this.lastFrame);\n }, intervalDuration);\n }\n\n public addFrame(frame: Buffer) {\n this.lastFrame = frame;\n }\n\n public endEncoding() {\n clearTimeout(this.intervalId!);\n this.inputStream!.end();\n }\n}","import * as puppeteer from 'puppeteer';\nimport * as cliProgress from 'cli-progress';\nimport {PNG, PNGWithMetadata} from 'pngjs';\nimport {Caption} from '../common/captions';\nimport {StepRenderer} from './step-renderer';\nimport {Args} from './cli';\nimport {AbstractRecorder} from './abstract-recorder';\n\nexport class StepRecorder extends AbstractRecorder {\n constructor(args: Args,\n private readonly captions: Caption[],\n private readonly renderer: StepRenderer,\n private readonly progressBar: cliProgress.SingleBar) {\n super(args);\n }\n\n public async recordCaptionsVideo(indexHtml: string) {\n this.progressBar.start(this.captions.length, 0);\n\n try {\n const videoElem = await this.launchBrowser(indexHtml);\n\n this.renderer.startEncoding();\n\n // Add empty frame before captions starts\n const beginningTime = this.captions[0].startTimeMs;\n this.renderer.addEmptyFrame(beginningTime);\n\n for (let i = 0; i < this.captions.length; i++) {\n const caption = this.captions[i];\n\n await this.nextStep();\n\n const screenShot = await this.takeScreenShot(videoElem!);\n this.renderer.addFrame(caption, screenShot);\n\n // Add delay before the next frame\n if (i < this.captions.length - 1) {\n const idleDelay = this.captions[i + 1].startTimeMs - caption.endTimeMs;\n if (idleDelay) {\n this.renderer.addEmptyFrame(idleDelay);\n }\n }\n\n this.progressBar.increment();\n }\n\n // Finish with en empty frame\n this.renderer.addEmptyFrame();\n\n this.progressBar.stop();\n await this.renderer.endEncoding();\n } catch (error) {\n console.error('Error during Puppeteer operation:', error);\n } finally {\n await this.browser?.close();\n }\n }\n\n private async nextStep() {\n await this.page!.evaluate(() => {\n window.Player.next();\n });\n }\n\n private async takeScreenShot(elem: puppeteer.ElementHandle): Promise {\n const screenshotBuffer = await elem.screenshot({\n encoding: 'binary',\n omitBackground: true,\n });\n return PNG.sync.read(Buffer.from(screenshotBuffer));\n }\n}","export class Timecode {\n public readonly hours: number;\n public readonly minutes: number;\n public readonly seconds: number;\n public readonly millis: number;\n\n constructor(millis: number) {\n this.millis = millis % 1000;\n\n this.hours = Math.floor(millis / 3_600_000);\n const remainingMillisAfterHours = millis % 3_600_000;\n this.minutes = Math.floor(remainingMillisAfterHours / 60_000);\n const remainingMillisAfterMinutes = remainingMillisAfterHours % 60_000;\n this.seconds = Math.floor(remainingMillisAfterMinutes / 1000);\n }\n\n public get hh(): string {\n return String(this.hours).padStart(2, '0');\n }\n\n public get mm(): string {\n return String(this.minutes).padStart(2, '0');\n }\n\n public get ss(): string {\n return String(this.seconds).padStart(2, '0');\n }\n public get SSS(): string {\n return String(this.millis).padStart(3, '0');\n }\n\n public get asString(): string {\n return `${this.hh}:${this.mm}:${this.ss},${this.SSS}`;\n }\n}\n\nexport function toMillis(timecodes: string): number {\n const parts = timecodes.split(/[:,]/).map(Number);\n\n const hours = parts[0];\n const minutes = parts[1];\n const seconds = parts[2];\n const milliseconds = parts[3];\n\n return hours * 3_600_000 // hours to millis\n + minutes * 60_000 // minutes to millis\n + seconds * 1000 // second to millis\n + milliseconds;\n}","import {toMillis} from './timecodes';\n\nconst indexLinePattern = /^\\d+$/;\nconst timecodesLinePattern = /^(\\d{2}:\\d{2}:\\d{2},\\d{3}) --> (\\d{2}:\\d{2}:\\d{2},\\d{3})$/;\nconst highlightedWordPattern = /^\\[(.+)](?:\\((\\w+)\\))?$/;\n\nexport interface Word {\n rawWord: string;\n isHighlighted: boolean;\n isBeforeHighlighted: boolean;\n isAfterHighlighted: boolean;\n highlightClass?: string;\n}\n\nexport interface Caption {\n index: number;\n startTimeMs: number;\n endTimeMs: number;\n words: Word[];\n}\n\nexport function haveSameWords(caption1: Caption, caption2: Caption): boolean {\n if (caption1.words.length != caption2.words.length) {\n return false;\n }\n\n for (let i =0; i < caption1.words.length; i++) {\n if (caption1.words[i].rawWord != caption2.words[i].rawWord) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function readCaptions(srtContent: string): Caption[] {\n const lines = srtContent.split('\\n');\n const captions: Caption[] = [];\n\n let index: number = 0;\n let timecodesStart: string | null = null;\n let timecodesEnd: string | null = null;\n\n for (const line of lines) {\n let match;\n if ((match = line.match(indexLinePattern))) {\n index = Number(line);\n } else if ((match = line.match(timecodesLinePattern))) {\n timecodesStart = match[1];\n timecodesEnd = match[2];\n } else if (line.length) {\n const start = toMillis(timecodesStart!);\n const end = toMillis(timecodesEnd!);\n\n const words = readWords(line);\n\n captions.push({\n index,\n words,\n startTimeMs: start,\n endTimeMs: end,\n });\n }\n }\n\n return captions;\n}\n\nexport function readWords(text: string): Word[] {\n const words = splitText(text);\n const highlightedIndex = words.findIndex(word => word.match(highlightedWordPattern));\n\n const res: Word[] = [];\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const match = word.match(highlightedWordPattern);\n const rawWord = match ? match[1] : word;\n const highlightClass = match && match[2] ? match[2] : null;\n\n const isHighlighted = Boolean(match);\n const isBeforeHighlighted = Boolean(~highlightedIndex && !isHighlighted && i < highlightedIndex);\n const isAfterHighlighted = Boolean(~highlightedIndex && !isHighlighted && i > highlightedIndex);\n\n const wordObject: Word = {\n rawWord,\n isHighlighted,\n isBeforeHighlighted,\n isAfterHighlighted,\n };\n\n if (highlightClass) {\n wordObject.highlightClass = highlightClass;\n }\n\n res.push(wordObject);\n }\n\n return res;\n}\n\nexport function splitText(text: string): string[] {\n const words: string[] = [];\n\n let currentWord = '';\n let isCurrentHighlighted = false;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const isWhitespace = /^\\s$/.test(char);\n const isPunctuation = /[,.!?]/.test(char);\n\n if (!isWhitespace) {\n if (!isPunctuation) {\n currentWord += char;\n switch (char) {\n case '[':\n case '(':\n isCurrentHighlighted = true;\n break;\n case ']':\n case ')':\n isCurrentHighlighted = false;\n break;\n }\n } else {\n if (currentWord) {\n currentWord += char;\n } else {\n // Attach punctuation mark to the previous word\n words[words.length - 1] += ' ' + char;\n }\n }\n } else {\n // char is a whitespace\n if (isCurrentHighlighted) {\n currentWord += char;\n } else if (currentWord) {\n words.push(currentWord);\n currentWord = '';\n }\n }\n }\n\n if (currentWord) {\n words.push(currentWord);\n }\n\n return words;\n}","import {createServer} from 'http-server';\n\nexport class WebServer {\n constructor(private readonly rootDir: string) {\n }\n\n public async start(relativePath = '') {\n return new Promise(async (resolve, reject) => {\n try {\n const server = createServer({ root: this.rootDir });\n const port = await WebServer.getFreePort();\n\n server.listen(port, async () => {\n try {\n const childProcess = await WebServer.openUrl(`http://127.0.0.1:${port}${relativePath}`);\n\n childProcess.on('close', () => {\n server.close(() => {\n resolve();\n });\n });\n } catch (error) {\n reject(error);\n }\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n private static async getFreePort(): Promise {\n const { default: getPort } = await import('get-port');\n return getPort();\n }\n\n private static async openUrl(url: string) {\n const { default: open } = await import('open');\n return open(url, { wait: true });\n }\n}","import {readFileSync} from 'fs';\nimport {Args, createProgressBar, parseArgs, printArgs} from './cli';\nimport {WorkDir} from './work-dir';\nimport {StepRenderer} from './step-renderer';\nimport {RealTimeRecorder} from './real-time-recorder';\nimport {RealTimeRenderer} from './real-time-renderer';\nimport {StepRecorder} from './step-recorder';\nimport {AbstractRecorder} from './abstract-recorder';\nimport {Caption, readCaptions} from '../common/captions';\nimport {WebServer} from '../common/web-server';\n\nfunction parseCaptions(srtCaptionsFile: string): Caption[] {\n const captionsSrc = readFileSync(srtCaptionsFile, 'utf-8');\n return readCaptions(captionsSrc);\n}\n\nfunction createRecorder(args: Args, captions: Caption[], workDir: WorkDir): AbstractRecorder {\n if (args.css3Animations) {\n const realTimeRenderer = new RealTimeRenderer(args);\n return new RealTimeRecorder(args, realTimeRenderer);\n } else {\n const progressBar = createProgressBar();\n const stepRenderer = new StepRenderer(args, workDir);\n return new StepRecorder(args, captions, stepRenderer, progressBar);\n }\n}\n\nconst cliArgs = parseArgs();\nconst captions = parseCaptions(cliArgs.srtInputFile);\nconst workDir = new WorkDir(captions, cliArgs);\n\n(async () => {\n try {\n const indexHtml = workDir.setup();\n printArgs(cliArgs);\n\n if (!cliArgs.isPreview) {\n const recorder = createRecorder(cliArgs, captions, workDir);\n await recorder.recordCaptionsVideo(indexHtml);\n } else {\n console.log('Launching preview server...');\n const previewServer = new WebServer(workDir.rootDir);\n await previewServer.start();\n }\n console.log('Done!');\n } catch (err) {\n console.error('Error occurred:', err);\n } finally {\n workDir.clear();\n }\n})();\n"],"names":["program","path","cliProgress","tmp","symlinkSync","mkdirSync","rmSync","writeFileSync","setFfmpegPath","PNG","appendFileSync","puppeteer","PassThrough","createServer","readFileSync"],"mappings":"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","x_google_ignoreList":[0,1]} \ No newline at end of file diff --git a/dist/web/index.js.map b/dist/web/index.js.map deleted file mode 100644 index f4884e3..0000000 --- a/dist/web/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sources":["../../src/common/timecodes.ts","../../src/common/captions.ts","../../src/web/caption-renderer.ts","../../src/web/player.ts","../../src/web/components/player.component.vue","../../src/script/dynamic-css-rules.ts","../../src/web/css-processor.ts","../../src/web/index.ts"],"sourcesContent":["export class Timecode {\n public readonly hours: number;\n public readonly minutes: number;\n public readonly seconds: number;\n public readonly millis: number;\n\n constructor(millis: number) {\n this.millis = millis % 1000;\n\n this.hours = Math.floor(millis / 3_600_000);\n const remainingMillisAfterHours = millis % 3_600_000;\n this.minutes = Math.floor(remainingMillisAfterHours / 60_000);\n const remainingMillisAfterMinutes = remainingMillisAfterHours % 60_000;\n this.seconds = Math.floor(remainingMillisAfterMinutes / 1000);\n }\n\n public get hh(): string {\n return String(this.hours).padStart(2, '0');\n }\n\n public get mm(): string {\n return String(this.minutes).padStart(2, '0');\n }\n\n public get ss(): string {\n return String(this.seconds).padStart(2, '0');\n }\n public get SSS(): string {\n return String(this.millis).padStart(3, '0');\n }\n\n public get asString(): string {\n return `${this.hh}:${this.mm}:${this.ss},${this.SSS}`;\n }\n}\n\nexport function toMillis(timecodes: string): number {\n const parts = timecodes.split(/[:,]/).map(Number);\n\n const hours = parts[0];\n const minutes = parts[1];\n const seconds = parts[2];\n const milliseconds = parts[3];\n\n return hours * 3_600_000 // hours to millis\n + minutes * 60_000 // minutes to millis\n + seconds * 1000 // second to millis\n + milliseconds;\n}","import {toMillis} from './timecodes';\n\nconst indexLinePattern = /^\\d+$/;\nconst timecodesLinePattern = /^(\\d{2}:\\d{2}:\\d{2},\\d{3}) --> (\\d{2}:\\d{2}:\\d{2},\\d{3})$/;\nconst highlightedWordPattern = /^\\[(.+)](?:\\((\\w+)\\))?$/;\n\nexport interface Word {\n rawWord: string;\n isHighlighted: boolean;\n isBeforeHighlighted: boolean;\n isAfterHighlighted: boolean;\n highlightClass?: string;\n}\n\nexport interface Caption {\n index: number;\n startTimeMs: number;\n endTimeMs: number;\n words: Word[];\n}\n\nexport function haveSameWords(caption1: Caption, caption2: Caption): boolean {\n if (caption1.words.length != caption2.words.length) {\n return false;\n }\n\n for (let i =0; i < caption1.words.length; i++) {\n if (caption1.words[i].rawWord != caption2.words[i].rawWord) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function readCaptions(srtContent: string): Caption[] {\n const lines = srtContent.split('\\n');\n const captions: Caption[] = [];\n\n let index: number = 0;\n let timecodesStart: string | null = null;\n let timecodesEnd: string | null = null;\n\n for (const line of lines) {\n let match;\n if ((match = line.match(indexLinePattern))) {\n index = Number(line);\n } else if ((match = line.match(timecodesLinePattern))) {\n timecodesStart = match[1];\n timecodesEnd = match[2];\n } else if (line.length) {\n const start = toMillis(timecodesStart!);\n const end = toMillis(timecodesEnd!);\n\n const words = readWords(line);\n\n captions.push({\n index,\n words,\n startTimeMs: start,\n endTimeMs: end,\n });\n }\n }\n\n return captions;\n}\n\nexport function readWords(text: string): Word[] {\n const words = splitText(text);\n const highlightedIndex = words.findIndex(word => word.match(highlightedWordPattern));\n\n const res: Word[] = [];\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const match = word.match(highlightedWordPattern);\n const rawWord = match ? match[1] : word;\n const highlightClass = match && match[2] ? match[2] : null;\n\n const isHighlighted = Boolean(match);\n const isBeforeHighlighted = Boolean(~highlightedIndex && !isHighlighted && i < highlightedIndex);\n const isAfterHighlighted = Boolean(~highlightedIndex && !isHighlighted && i > highlightedIndex);\n\n const wordObject: Word = {\n rawWord,\n isHighlighted,\n isBeforeHighlighted,\n isAfterHighlighted,\n };\n\n if (highlightClass) {\n wordObject.highlightClass = highlightClass;\n }\n\n res.push(wordObject);\n }\n\n return res;\n}\n\nexport function splitText(text: string): string[] {\n const words: string[] = [];\n\n let currentWord = '';\n let isCurrentHighlighted = false;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const isWhitespace = /^\\s$/.test(char);\n const isPunctuation = /[,.!?]/.test(char);\n\n if (!isWhitespace) {\n if (!isPunctuation) {\n currentWord += char;\n switch (char) {\n case '[':\n case '(':\n isCurrentHighlighted = true;\n break;\n case ']':\n case ')':\n isCurrentHighlighted = false;\n break;\n }\n } else {\n if (currentWord) {\n currentWord += char;\n } else {\n // Attach punctuation mark to the previous word\n words[words.length - 1] += ' ' + char;\n }\n }\n } else {\n // char is a whitespace\n if (isCurrentHighlighted) {\n currentWord += char;\n } else if (currentWord) {\n words.push(currentWord);\n currentWord = '';\n }\n }\n }\n\n if (currentWord) {\n words.push(currentWord);\n }\n\n return words;\n}","import {Caption, Word} from '../common/captions';\nimport {CssProcessor} from './css-processor';\n\nexport class CaptionRenderer {\n public constructor(private readonly cssProcessor: CssProcessor) {\n }\n\n public renderCaption(caption: Caption): HTMLDivElement {\n const captionDiv = document.createElement('div');\n captionDiv.setAttribute('id', `caption_${caption.index}`);\n captionDiv.setAttribute('class', 'caption');\n\n caption.words\n .map(word => this.renderWord(word, caption))\n .forEach(spanElem => captionDiv.appendChild(spanElem));\n\n const captionWords = caption.words.map(word => word.rawWord);\n return this.cssProcessor.applyDynamicClasses(captionDiv, caption.index, caption.startTimeMs, captionWords);\n }\n\n private renderWord(word: Word, caption: Caption): HTMLSpanElement {\n const cssClasses = CaptionRenderer.wordSpanClasses(word);\n const wordSpan = document.createElement('span');\n wordSpan.textContent = word.rawWord;\n wordSpan.classList.add(...cssClasses);\n\n return this.cssProcessor.applyDynamicClasses(wordSpan, caption.index, caption.startTimeMs, [ word.rawWord ]);\n }\n\n public static wordSpanClasses(word: Word): Set {\n const cssClasses = new Set([ 'word' ]);\n\n if (word.isHighlighted) {\n cssClasses.add(word.highlightClass || 'highlighted');\n } if (word.isBeforeHighlighted) {\n cssClasses.add('before-highlighted');\n } if (word.isAfterHighlighted) {\n cssClasses.add('after-highlighted');\n }\n\n return cssClasses;\n }\n}","import {Caption, haveSameWords} from '../common/captions';\nimport {CaptionRenderer} from './caption-renderer';\nimport {CssProcessor} from './css-processor';\n\nexport class Player {\n public onStop = () => {};\n\n private readonly captionsContainer: HTMLDivElement;\n private readonly rendered: HTMLDivElement[] = [];\n private timeoutIds: NodeJS.Timeout[] = [];\n private displayedCaptionId = 0;\n\n constructor(private readonly videoElem: HTMLElement,\n private readonly captions: Caption[],\n private readonly cssProcessor: CssProcessor,\n renderer: CaptionRenderer) {\n this.captionsContainer = this.videoElem.querySelector('.captions')!;\n\n for (let i = 0; i < captions.length; i++) {\n const caption = captions[i];\n this.rendered[caption.index] = i > 0 && haveSameWords(caption, captions[i - 1])\n ? this.rendered[caption.index - 1]\n : renderer.renderCaption(caption);\n }\n }\n\n public play() {\n this.rendered.forEach(captionElem => captionElem.remove());\n\n if (this.captions.length === 0) {\n return;\n }\n\n for (let i = 0; i < this.captions.length; i++) {\n const caption = this.captions[i];\n const displayTimeoutId = setTimeout(() => {\n this.displayCaption(caption.index);\n }, caption.startTimeMs);\n this.timeoutIds.push(displayTimeoutId);\n\n if (i < this.captions.length - 1) {\n const nextCaption = this.captions[i + 1];\n\n if (!haveSameWords(caption, nextCaption)) {\n const hideTimeoutId = setTimeout(() => {\n this.hideCaption(caption.index);\n }, caption.endTimeMs);\n this.timeoutIds.push(hideTimeoutId);\n }\n } else {\n const hideTimeoutId = setTimeout(() => {\n this.hideCaption(caption.index);\n this.stop();\n }, caption.endTimeMs);\n this.timeoutIds.push(hideTimeoutId);\n }\n }\n }\n\n public stop() {\n if (this.displayedCaptionId) {\n this.rendered[this.displayedCaptionId].remove();\n this.displayedCaptionId = 0;\n }\n\n while (this.timeoutIds.length) {\n clearTimeout(this.timeoutIds.pop());\n }\n\n this.onStop();\n }\n\n public prec() {\n if (!this.isBeginning) {\n let precId = this.displayedCaptionId - 1;\n if (precId) {\n this.displayCaption(precId);\n } else {\n this.hideCaption(this.displayedCaptionId)\n }\n }\n }\n\n public next() {\n if (!this.isEnd) {\n this.displayCaption(this.displayedCaptionId + 1);\n }\n }\n\n public get isBeginning(): boolean {\n return this.displayedCaptionId === 0;\n }\n\n public get isEnd(): boolean {\n return this.displayedCaptionId === this.captions.length\n }\n\n private displayCaption(index: number) {\n if (this.displayedCaptionId === index) {\n return; // Displayed already, do nothing\n }\n\n if (this.displayedCaptionId) {\n const displayedCaption = this.captions[this.displayedCaptionId - 1];\n const nextCaption = this.captions[index - 1];\n\n if (haveSameWords(displayedCaption, nextCaption)) {\n const renderedCaption = this.rendered[this.displayedCaptionId];\n\n const captionWords = nextCaption.words.map(word => word.rawWord);\n this.cssProcessor.applyDynamicClasses(renderedCaption, index, nextCaption.startTimeMs, captionWords);\n\n const renderedWords = renderedCaption.querySelectorAll('.word');\n for (let i = 0; i < renderedWords.length; i++) {\n const word = nextCaption.words[i];\n const renderedWord = renderedWords[i] as HTMLElement;\n\n const cssClasses = CaptionRenderer.wordSpanClasses(word);\n const existingClasses = new Set([...renderedWord.classList.values()]);\n\n const classesToRemove = existingClasses.difference(cssClasses);\n const classesToAdd = cssClasses.difference(existingClasses);\n\n renderedWord.classList.remove(...classesToRemove);\n renderedWord.classList.add(...classesToAdd);\n\n this.cssProcessor.applyDynamicClasses(renderedWord, index, nextCaption.startTimeMs, [ word.rawWord ]);\n }\n } else {\n this.rendered[this.displayedCaptionId].remove();\n this.captionsContainer.appendChild(this.rendered[index]);\n }\n } else {\n this.captionsContainer.appendChild(this.rendered[index]);\n }\n\n this.dynamicallyStyleContainers(index);\n this.displayedCaptionId = index;\n }\n\n private dynamicallyStyleContainers(index: number) {\n this.videoElem.setAttribute('class', '');\n this.captionsContainer.setAttribute('class', 'captions');\n\n const caption = this.captions[index - 1];\n const captionWords = caption.words.map(word => word.rawWord);\n this.cssProcessor.applyDynamicClasses(this.videoElem, index, caption.startTimeMs, captionWords);\n this.cssProcessor.applyDynamicClasses(this.captionsContainer, index, caption.startTimeMs, captionWords);\n }\n\n private hideCaption(index: number) {\n if (this.displayedCaptionId != index) {\n return; // Removed already, do nothing\n }\n\n this.rendered[index].remove();\n this.displayedCaptionId = 0;\n }\n}","\n\n","import {toMillis} from '../common/timecodes';\n\nexport type FilterType = 'indexes' | 'timecodes' | 'words';\n\nexport interface Filter {\n cssClass: string;\n type: FilterType;\n args: string[];\n}\n\nexport function normalizeTimecode(timecode: string): string {\n const [ hh, mm, ss, ms ] = timecode.split(/[^\\d]+/);\n return `${hh}:${mm}:${ss}.${ms}`;\n}\n\nexport abstract class AbstractDynamicCssRule {\n protected constructor(protected readonly targetSelectors: string[],\n public readonly appliedCssClass: string) {\n }\n\n public isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n let targetClasses = target.getAttribute('class')?.split(' ') || [];\n\n for (const targetSelector of this.targetSelectors) {\n if (targetSelector.startsWith('#')) {\n const idSelector = targetSelector.slice(1);\n if (target.getAttribute('id') != idSelector) {\n return false;\n }\n } else if (targetSelector.startsWith('.')) {\n const classSelector = targetSelector.slice(1);\n if (!targetClasses.includes(classSelector)) {\n return false;\n }\n } else {\n throw new Error(`Unsupported target selector: '${targetSelector}'`);\n }\n }\n\n return true;\n }\n}\n\nexport class IndexesDynamicCssRule extends AbstractDynamicCssRule {\n constructor(targetSelectors: string[],\n appliedCssClass: string,\n private readonly startIndexInclusive: number,\n private readonly endIndexInclusive?: number) {\n super(targetSelectors, appliedCssClass);\n }\n\n isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n return super.isApplied(target, captionIndex, timeMs, words)\n && this.startIndexInclusive <= captionIndex\n && (this.endIndexInclusive ? this.endIndexInclusive >= captionIndex : true);\n }\n}\n\nexport class TimecodesDynamicCssRule extends AbstractDynamicCssRule {\n constructor(targetSelectors: string[],\n appliedCssClass: string,\n private readonly startTimeMsInclusive: number,\n private readonly endTimeMsInclusive?: number) {\n super(targetSelectors, appliedCssClass);\n }\n\n isApplied(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): boolean {\n return super.isApplied(target, captionIndex, timeMs, words)\n && this.startTimeMsInclusive <= timeMs\n && (this.endTimeMsInclusive ? this.endTimeMsInclusive >= timeMs : true);\n }\n}\n\nexport function createDynamicCssRule(targetSelectors: string[], filter: Filter): AbstractDynamicCssRule {\n switch (filter.type) {\n case 'indexes':\n const [ startIndex, endIndex ] = filter.args.map(arg => Number(arg));\n return new IndexesDynamicCssRule(targetSelectors, filter.cssClass, startIndex, endIndex);\n case 'timecodes':\n const [ startMs, endMs ] = filter.args.map(normalizeTimecode).map(toMillis);\n return new TimecodesDynamicCssRule(targetSelectors, filter.cssClass, startMs, endMs);\n default:\n throw new Error(`Unknown filter type '${filter.type}'!`);\n }\n}","import {AbstractDynamicCssRule, createDynamicCssRule, Filter, FilterType} from '../script/dynamic-css-rules';\n\nconst dynamicCssClassPrefix = 'pup-';\nconst dynamicCssClassPattern = /^\\.pup-(\\w+)((?:-[^-]+)+)$/;\n\nexport class CssProcessor {\n private readonly dynamicCssRules: AbstractDynamicCssRule[] = [];\n\n constructor() {\n for (const styleSheet of document.styleSheets) {\n for (const styleRule of styleSheet.cssRules) {\n const selectorText = (styleRule as CSSStyleRule).selectorText || '';\n\n if (selectorText.includes('.pup-')) {\n const selectors = CssProcessor.parseSelectors(selectorText);\n const targetSelectors: string[] = [];\n let filter: Filter | null = null;\n\n for (const selector of selectors) {\n if (selector.match(dynamicCssClassPattern)) {\n if (filter) {\n throw new Error(\n `Only one dynamic CSS class is allowed per style rule. \n Two dynamic classes were found: .${filter.cssClass} and ${selector}`);\n }\n\n filter = CssProcessor.parseFilter(selector);\n } else {\n targetSelectors.push(selector);\n }\n }\n\n const rule = createDynamicCssRule(targetSelectors, filter!);\n this.dynamicCssRules.push(rule);\n }\n }\n }\n }\n\n public applyDynamicClasses(target: T, captionIndex: number, timeMs: number, words: string[]): T {\n const dynamicCssClasses = this.dynamicCssClasses(target, captionIndex, timeMs, words);\n const existingDynamicClasses = CssProcessor.getDynamicCssClassesFromElem(target);\n\n const classesToRemove = existingDynamicClasses.difference(dynamicCssClasses);\n const classesToAdd = dynamicCssClasses.difference(classesToRemove);\n\n target.classList.remove(...classesToRemove);\n target.classList.add(...classesToAdd);\n\n return target;\n }\n\n private dynamicCssClasses(target: HTMLElement, captionIndex: number, timeMs: number, words: string[]): Set {\n const cssClasses = this.dynamicCssRules\n .filter(rule => rule.isApplied(target, captionIndex, timeMs, words))\n .map(rule => rule.appliedCssClass);\n return new Set(cssClasses);\n }\n\n public static getDynamicCssClassesFromElem(elem: HTMLElement): Set {\n const dynamicCssClasses = [...elem.classList.values()]\n .filter(cssClass => cssClass.startsWith(dynamicCssClassPrefix));\n return new Set(dynamicCssClasses);\n }\n\n static parseFilter(dynamicCssClass: string): Filter {\n const match = dynamicCssClass.match(dynamicCssClassPattern);\n\n if (!match) {\n throw new Error(`CSS class ${dynamicCssClass} do not match required pattern!`);\n }\n\n const cssClass = dynamicCssClass.slice(1);\n const filterType = match[1] as FilterType;\n const filterArgs = match[2].split('-').slice(1);\n\n return {\n cssClass,\n type: filterType,\n args: filterArgs,\n }\n }\n\n static parseSelectors(selectorText: string): string[] {\n const selectors: string[] = [];\n let currentToken = '';\n let lastIsEscaped = false;\n\n for (let i = 0; i < selectorText.length; i++) {\n const char = selectorText[i];\n if ((char === '.' || char === '#') && !lastIsEscaped) {\n if (currentToken) {\n selectors.push(currentToken);\n }\n currentToken = char;\n } else if (char === '\\\\') {\n currentToken += char;\n lastIsEscaped = true;\n } else if (lastIsEscaped) {\n currentToken += char;\n lastIsEscaped = false;\n } else {\n currentToken += char;\n }\n }\n\n if (currentToken) {\n selectors.push(currentToken);\n }\n\n return selectors;\n }\n}\n","import {createApp} from 'vue';\nimport {Player} from './player';\nimport PlayerComponent from './components/player.component.vue';\nimport {CssProcessor} from './css-processor';\nimport {CaptionRenderer} from './caption-renderer';\n\nwindow.ready = new Promise((resolve, reject) => {\n window.onload = () => {\n const videoElem = document.getElementById('video');\n const cssProcessor = new CssProcessor();\n const renderer = new CaptionRenderer(cssProcessor);\n window.Player = new Player(videoElem!, window.captions, cssProcessor, renderer);\n\n if (window.playerArgs.isPreview) {\n createApp({})\n .component('player', PlayerComponent)\n .mount('#player-controller');\n }\n\n resolve();\n };\n});\n"],"names":["reactive","createApp","PlayerComponent"],"mappings":"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"} \ No newline at end of file diff --git a/rollup.config.mjs b/rollup.config.mjs index 2b09b58..722a8fa 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -6,9 +6,9 @@ import vue from 'rollup-plugin-vue'; import copy from 'rollup-plugin-copy'; export default [{ - input: 'src/web/index.ts', + input: 'src/player/index.ts', output: { - file: 'dist/web/index.js', + file: 'dist/player/index.js', format: 'iife', sourcemap: true, globals: { @@ -17,7 +17,7 @@ export default [{ }, plugins: [ typescript({ - tsconfig: './src/web/tsconfig.json', + tsconfig: './src/player/tsconfig.json', }), vue(), resolve({ diff --git a/src/script/dynamic-css-rules.ts b/src/common/dynamic-css-rules.ts similarity index 100% rename from src/script/dynamic-css-rules.ts rename to src/common/dynamic-css-rules.ts diff --git a/src/web/caption-renderer.ts b/src/player/caption-renderer.ts similarity index 100% rename from src/web/caption-renderer.ts rename to src/player/caption-renderer.ts diff --git a/src/web/components/player.component.vue b/src/player/components/player.component.vue similarity index 100% rename from src/web/components/player.component.vue rename to src/player/components/player.component.vue diff --git a/src/web/css-processor.ts b/src/player/css-processor.ts similarity index 98% rename from src/web/css-processor.ts rename to src/player/css-processor.ts index c906457..7e169c0 100644 --- a/src/web/css-processor.ts +++ b/src/player/css-processor.ts @@ -1,4 +1,4 @@ -import {AbstractDynamicCssRule, createDynamicCssRule, Filter, FilterType} from '../script/dynamic-css-rules'; +import {AbstractDynamicCssRule, createDynamicCssRule, Filter, FilterType} from '../common/dynamic-css-rules'; const dynamicCssClassPrefix = 'pup-'; const dynamicCssClassPattern = /^\.pup-(\w+)((?:-[^-]+)+)$/; diff --git a/src/web/index.ts b/src/player/index.ts similarity index 100% rename from src/web/index.ts rename to src/player/index.ts diff --git a/src/web/player.ts b/src/player/player.ts similarity index 100% rename from src/web/player.ts rename to src/player/player.ts diff --git a/src/web/tsconfig.json b/src/player/tsconfig.json similarity index 100% rename from src/web/tsconfig.json rename to src/player/tsconfig.json diff --git a/src/script/assets.ts b/src/script/assets.ts index 1c3ad80..fd18229 100644 --- a/src/script/assets.ts +++ b/src/script/assets.ts @@ -4,6 +4,6 @@ export const assetsFolder = path.join(__dirname, '..', '..', 'assets'); export const defaultStylesCss = path.join(assetsFolder, 'captions.css'); export const indexHtml = path.join(assetsFolder, 'index.html'); -export const indexJs = path.join(__dirname, '..', 'web', 'index.js'); +export const indexJs = path.join(__dirname, '..', 'player', 'index.js'); export const nodeModules = path.join(__dirname, '..', '..', 'node_modules'); diff --git a/src/types/window.d.ts b/src/types/window.d.ts index b36255b..e46d618 100644 --- a/src/types/window.d.ts +++ b/src/types/window.d.ts @@ -1,5 +1,5 @@ import {Caption} from '../common/captions'; -import {Player} from '../web/player'; +import {Player} from '../player/player'; import {PlayerArgs} from '../common/player-args'; declare global { diff --git a/test/web/css-processor.test.ts b/test/web/css-processor.test.ts index 5387764..89c69f6 100644 --- a/test/web/css-processor.test.ts +++ b/test/web/css-processor.test.ts @@ -1,5 +1,5 @@ import {expect} from 'chai'; -import {CssProcessor} from '../../src/web/css-processor'; +import {CssProcessor} from '../../src/player/css-processor'; describe('CssProcessor', () => { it('parseFilter', () => {