You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

643 lines
24 KiB

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// node_modules/node-webvtt/lib/parser.js
var require_parser = __commonJS({
"node_modules/node-webvtt/lib/parser.js"(exports, module2) {
"use strict";
function ParserError(message, error) {
this.message = message;
this.error = error;
}
ParserError.prototype = Object.create(Error.prototype);
var TIMESTAMP_REGEXP = /([0-9]{1,2})?:?([0-9]{2}):([0-9]{2}\.[0-9]{2,3})/;
function parse2(input, options) {
if (!options) {
options = {};
}
const { meta = false, strict = true } = options;
if (typeof input !== "string") {
throw new ParserError("Input must be a string");
}
input = input.trim();
input = input.replace(/\r\n/g, "\n");
input = input.replace(/\r/g, "\n");
const parts = input.split("\n\n");
const header = parts.shift();
if (!header.startsWith("WEBVTT")) {
throw new ParserError('Must start with "WEBVTT"');
}
const headerParts = header.split("\n");
const headerComments = headerParts[0].replace("WEBVTT", "");
if (headerComments.length > 0 && (headerComments[0] !== " " && headerComments[0] !== " ")) {
throw new ParserError("Header comment must start with space or tab");
}
if (parts.length === 0 && headerParts.length === 1) {
return { valid: true, strict, cues: [], errors: [] };
}
if (!meta && headerParts.length > 1 && headerParts[1] !== "") {
throw new ParserError("Missing blank line after signature");
}
const { cues, errors } = parseCues(parts, strict);
if (strict && errors.length > 0) {
throw errors[0];
}
const headerMeta = meta ? parseMeta(headerParts) : null;
const result = { valid: errors.length === 0, strict, cues, errors };
if (meta) {
result.meta = headerMeta;
}
return result;
}
function parseMeta(headerParts) {
const meta = {};
headerParts.slice(1).forEach((header) => {
const splitIdx = header.indexOf(":");
const key = header.slice(0, splitIdx).trim();
const value = header.slice(splitIdx + 1).trim();
meta[key] = value;
});
return Object.keys(meta).length > 0 ? meta : null;
}
function parseCues(cues, strict) {
const errors = [];
const parsedCues = cues.map((cue, i) => {
try {
return parseCue(cue, i, strict);
} catch (e) {
errors.push(e);
return null;
}
}).filter(Boolean);
return {
cues: parsedCues,
errors
};
}
function parseCue(cue, i, strict) {
let identifier = "";
let start = 0;
let end = 0.01;
let text = "";
let styles = "";
const lines = cue.split("\n").filter(Boolean);
if (lines.length > 0 && lines[0].trim().startsWith("NOTE")) {
return null;
}
if (lines.length === 1 && !lines[0].includes("-->")) {
throw new ParserError(`Cue identifier cannot be standalone (cue #${i})`);
}
if (lines.length > 1 && !(lines[0].includes("-->") || lines[1].includes("-->"))) {
const msg = `Cue identifier needs to be followed by timestamp (cue #${i})`;
throw new ParserError(msg);
}
if (lines.length > 1 && lines[1].includes("-->")) {
identifier = lines.shift();
}
const times = typeof lines[0] === "string" && lines[0].split(" --> ");
if (times.length !== 2 || !validTimestamp(times[0]) || !validTimestamp(times[1])) {
throw new ParserError(`Invalid cue timestamp (cue #${i})`);
}
start = parseTimestamp(times[0]);
end = parseTimestamp(times[1]);
if (strict) {
if (start > end) {
throw new ParserError(`Start timestamp greater than end (cue #${i})`);
}
if (end <= start) {
throw new ParserError(`End must be greater than start (cue #${i})`);
}
}
if (!strict && end < start) {
throw new ParserError(`End must be greater or equal to start when not strict (cue #${i})`);
}
styles = times[1].replace(TIMESTAMP_REGEXP, "").trim();
lines.shift();
text = lines.join("\n");
if (!text) {
return false;
}
return { identifier, start, end, text, styles };
}
function validTimestamp(timestamp) {
return TIMESTAMP_REGEXP.test(timestamp);
}
function parseTimestamp(timestamp) {
const matches = timestamp.match(TIMESTAMP_REGEXP);
let secs = parseFloat(matches[1] || 0) * 60 * 60;
secs += parseFloat(matches[2]) * 60;
secs += parseFloat(matches[3]);
return secs;
}
module2.exports = { ParserError, parse: parse2 };
}
});
// node_modules/node-webvtt/lib/compiler.js
var require_compiler = __commonJS({
"node_modules/node-webvtt/lib/compiler.js"(exports, module2) {
"use strict";
function CompilerError(message, error) {
this.message = message;
this.error = error;
}
CompilerError.prototype = Object.create(Error.prototype);
function compile(input) {
if (!input) {
throw new CompilerError("Input must be non-null");
}
if (typeof input !== "object") {
throw new CompilerError("Input must be an object");
}
if (Array.isArray(input)) {
throw new CompilerError("Input cannot be array");
}
if (!input.valid) {
throw new CompilerError("Input must be valid");
}
let output = "WEBVTT\n";
if (input.meta) {
if (typeof input.meta !== "object" || Array.isArray(input.meta)) {
throw new CompilerError("Metadata must be an object");
}
Object.entries(input.meta).forEach((i) => {
if (typeof i[1] !== "string") {
throw new CompilerError(`Metadata value for "${i[0]}" must be string`);
}
output += `${i[0]}: ${i[1]}
`;
});
}
let lastTime = null;
input.cues.forEach((cue, index) => {
if (lastTime && lastTime > cue.start) {
throw new CompilerError(`Cue number ${index} is not in chronological order`);
}
lastTime = cue.start;
output += "\n";
output += compileCue(cue);
output += "\n";
});
return output;
}
function compileCue(cue) {
if (typeof cue !== "object") {
throw new CompilerError("Cue malformed: not of type object");
}
if (typeof cue.identifier !== "string" && typeof cue.identifier !== "number" && cue.identifier !== null) {
throw new CompilerError(`Cue malformed: identifier value is not a string.
${JSON.stringify(cue)}`);
}
if (isNaN(cue.start)) {
throw new CompilerError(`Cue malformed: null start value.
${JSON.stringify(cue)}`);
}
if (isNaN(cue.end)) {
throw new CompilerError(`Cue malformed: null end value.
${JSON.stringify(cue)}`);
}
if (cue.start >= cue.end) {
throw new CompilerError(`Cue malformed: start timestamp greater than end
${JSON.stringify(cue)}`);
}
if (typeof cue.text !== "string") {
throw new CompilerError(`Cue malformed: null text value.
${JSON.stringify(cue)}`);
}
if (typeof cue.styles !== "string") {
throw new CompilerError(`Cue malformed: null styles value.
${JSON.stringify(cue)}`);
}
let output = "";
if (cue.identifier.length > 0) {
output += `${cue.identifier}
`;
}
const startTimestamp = convertTimestamp(cue.start);
const endTimestamp = convertTimestamp(cue.end);
output += `${startTimestamp} --> ${endTimestamp}`;
output += cue.styles ? ` ${cue.styles}` : "";
output += `
${cue.text}`;
return output;
}
function convertTimestamp(time) {
const hours = pad(calculateHours(time), 2);
const minutes = pad(calculateMinutes(time), 2);
const seconds = pad(calculateSeconds(time), 2);
const milliseconds = pad(calculateMs(time), 3);
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
}
function pad(num, zeroes) {
let output = `${num}`;
while (output.length < zeroes) {
output = `0${output}`;
}
return output;
}
function calculateHours(time) {
return Math.floor(time / 60 / 60);
}
function calculateMinutes(time) {
return Math.floor(time / 60) % 60;
}
function calculateSeconds(time) {
return Math.floor(time % 60);
}
function calculateMs(time) {
return Math.floor((time % 1).toFixed(4) * 1e3);
}
module2.exports = { CompilerError, compile };
}
});
// node_modules/node-webvtt/lib/segmenter.js
var require_segmenter = __commonJS({
"node_modules/node-webvtt/lib/segmenter.js"(exports, module2) {
"use strict";
var parse2 = require_parser().parse;
function segment(input, segmentLength) {
segmentLength = segmentLength || 10;
const parsed = parse2(input);
const segments = [];
let cues = [];
let queuedCue = null;
let currentSegmentDuration = 0;
let totalSegmentsDuration = 0;
parsed.cues.forEach((cue, i) => {
const firstCue = i === 0;
const lastCue = i === parsed.cues.length - 1;
const start = cue.start;
const end = cue.end;
const nextStart = lastCue ? Infinity : parsed.cues[i + 1].start;
const cueLength = firstCue ? end : end - start;
const silence = firstCue ? 0 : start - parsed.cues[i - 1].end;
currentSegmentDuration = currentSegmentDuration + cueLength + silence;
debug("------------");
debug(`Cue #${i}, segment #${segments.length + 1}`);
debug(`Start ${start}`);
debug(`End ${end}`);
debug(`Length ${cueLength}`);
debug(`Total segment duration = ${totalSegmentsDuration}`);
debug(`Current segment duration = ${currentSegmentDuration}`);
debug(`Start of next = ${nextStart}`);
if (queuedCue) {
cues.push(queuedCue);
currentSegmentDuration += queuedCue.end - totalSegmentsDuration;
queuedCue = null;
}
cues.push(cue);
let shouldQueue = nextStart - end < segmentLength && silence < segmentLength && currentSegmentDuration > segmentLength;
if (shouldSegment(totalSegmentsDuration, segmentLength, nextStart, silence)) {
const duration = segmentDuration(lastCue, end, segmentLength, currentSegmentDuration, totalSegmentsDuration);
segments.push({ duration, cues });
totalSegmentsDuration += duration;
currentSegmentDuration = 0;
cues = [];
} else {
shouldQueue = false;
}
if (shouldQueue) {
queuedCue = cue;
}
});
return segments;
}
function shouldSegment(total, length, nextStart, silence) {
const x = alignToSegmentLength(silence, length);
const nextCueIsInNextSegment = silence <= length || x + total < nextStart;
return nextCueIsInNextSegment && nextStart - total >= length;
}
function segmentDuration(lastCue, end, length, currentSegment, totalSegments) {
let duration = length;
if (currentSegment > length) {
duration = alignToSegmentLength(currentSegment - length, length);
}
if (lastCue) {
duration = parseFloat((end - totalSegments).toFixed(2));
} else {
duration = Math.round(duration);
}
return duration;
}
function alignToSegmentLength(n, segmentLength) {
n += segmentLength - n % segmentLength;
return n;
}
var debugging = false;
function debug(m) {
if (debugging) {
console.log(m);
}
}
module2.exports = { segment };
}
});
// node_modules/node-webvtt/lib/hls.js
var require_hls = __commonJS({
"node_modules/node-webvtt/lib/hls.js"(exports, module2) {
"use strict";
var segment = require_segmenter().segment;
function hlsSegment(input, segmentLength, startOffset) {
if (typeof startOffset === "undefined") {
startOffset = "900000";
}
const segments = segment(input, segmentLength);
const result = [];
segments.forEach((seg, i) => {
const content = `WEBVTT
X-TIMESTAMP-MAP=MPEGTS:${startOffset},LOCAL:00:00:00.000
${printableCues(seg.cues)}
`;
const filename = generateSegmentFilename(i);
result.push({ filename, content });
});
return result;
}
function hlsSegmentPlaylist(input, segmentLength) {
const segmented = segment(input, segmentLength);
const printable = printableSegments(segmented);
const longestSegment = Math.round(findLongestSegment(segmented));
const template = `#EXTM3U
#EXT-X-TARGETDURATION:${longestSegment}
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
${printable}
#EXT-X-ENDLIST
`;
return template;
}
function pad(num, n) {
const padding = "0".repeat(Math.max(0, n - num.toString().length));
return `${padding}${num}`;
}
function generateSegmentFilename(index) {
return `${index}.vtt`;
}
function printableSegments(segments) {
const result = [];
segments.forEach((seg, i) => {
result.push(`#EXTINF:${seg.duration.toFixed(5)},
${generateSegmentFilename(i)}`);
});
return result.join("\n");
}
function findLongestSegment(segments) {
let max = 0;
segments.forEach((seg) => {
if (seg.duration > max) {
max = seg.duration;
}
});
return max;
}
function printableCues(cues) {
const result = [];
cues.forEach((cue) => {
result.push(printableCue(cue));
});
return result.join("\n\n");
}
function printableCue(cue) {
const printable = [];
if (cue.identifier) {
printable.push(cue.identifier);
}
const start = printableTimestamp(cue.start);
const end = printableTimestamp(cue.end);
const styles = cue.styles ? `${cue.styles}` : "";
printable.push(`${start} --> ${end} ${styles}`);
printable.push(cue.text);
return printable.join("\n");
}
function printableTimestamp(timestamp) {
const ms = (timestamp % 1).toFixed(3);
timestamp = Math.round(timestamp - ms);
const hours = Math.floor(timestamp / 3600);
const mins = Math.floor((timestamp - hours * 3600) / 60);
const secs = timestamp - hours * 3600 - mins * 60;
const hourString = `${pad(hours, 2)}:`;
return `${hourString}${pad(mins, 2)}:${pad(secs, 2)}.${pad(ms * 1e3, 3)}`;
}
module2.exports = { hlsSegment, hlsSegmentPlaylist };
}
});
// node_modules/node-webvtt/index.js
var require_node_webvtt = __commonJS({
"node_modules/node-webvtt/index.js"(exports, module2) {
"use strict";
var parse2 = require_parser().parse;
var compile = require_compiler().compile;
var segment = require_segmenter().segment;
var hls = require_hls();
module2.exports = { parse: parse2, compile, segment, hls };
}
});
// main.ts
__export(exports, {
default: () => ChatViewPlugin
});
var import_obsidian = __toModule(require("obsidian"));
var webvtt = __toModule(require_node_webvtt());
var KEYMAP = { ">": "right", "<": "left", "^": "center" };
var CONFIGS = {
"header": ["h2", "h3", "h4", "h5", "h6"],
"mw": ["50", "55", "60", "65", "70", "75", "80", "85", "90"],
"mode": ["default", "minimal"]
};
var COLORS = [
"red",
"orange",
"yellow",
"green",
"blue",
"purple",
"grey",
"brown",
"indigo",
"teal",
"pink",
"slate",
"wood"
];
var _ChatPatterns = class {
};
var ChatPatterns = _ChatPatterns;
ChatPatterns.message = /(^>|<|\^)/;
ChatPatterns.delimiter = /.../;
ChatPatterns.comment = /^#/;
ChatPatterns.colors = /\[(.*?)\]/;
ChatPatterns.format = /{(.*?)}/;
ChatPatterns.joined = RegExp([_ChatPatterns.message, _ChatPatterns.delimiter, _ChatPatterns.colors, _ChatPatterns.comment, _ChatPatterns.format].map((pattern) => pattern.source).join("|"));
ChatPatterns.voice = /<v\s+([^>]+)>([^<]+)<\/v>/;
var ChatViewPlugin = class extends import_obsidian.Plugin {
onload() {
return __async(this, null, function* () {
this.registerMarkdownCodeBlockProcessor("chat-webvtt", (source, el, _) => {
const vtt = webvtt.parse(source, { meta: true });
const messages = [];
const self = vtt.meta && "Self" in vtt.meta ? vtt.meta.Self : void 0;
const selves = self ? self.split(",").map((val) => val.trim()) : void 0;
const formatConfigs = new Map();
const maxWidth = vtt.meta && "MaxWidth" in vtt.meta ? vtt.meta.MaxWidth : void 0;
const headerConfig = vtt.meta && "Header" in vtt.meta ? vtt.meta.Header : void 0;
const modeConfig = vtt.meta && "Mode" in vtt.meta ? vtt.meta.Mode : void 0;
if (CONFIGS["mw"].contains(maxWidth))
formatConfigs.set("mw", maxWidth);
if (CONFIGS["header"].contains(headerConfig))
formatConfigs.set("header", headerConfig);
if (CONFIGS["mode"].contains(modeConfig))
formatConfigs.set("mode", modeConfig);
console.log(formatConfigs);
for (let index = 0; index < vtt.cues.length; index++) {
const cue = vtt.cues[index];
const start = (0, import_obsidian.moment)(Math.round(cue.start * 1e3)).format("HH:mm:ss.SSS");
const end = (0, import_obsidian.moment)(Math.round(cue.end * 1e3)).format("HH:mm:ss.SSS");
if (ChatPatterns.voice.test(cue.text)) {
const matches = cue.text.match(ChatPatterns.voice);
messages.push({ header: matches[1], body: matches[2], subtext: `${start} to ${end}` });
} else {
messages.push({ header: "", body: cue.text, subtext: `${start} to ${end}` });
}
}
const headers = messages.map((message) => message.header);
const uniqueHeaders = new Set(headers);
uniqueHeaders.delete("");
console.log(messages);
console.log(uniqueHeaders);
const colorConfigs = new Map();
Array.from(uniqueHeaders).forEach((h, i) => colorConfigs.set(h, COLORS[i % COLORS.length]));
console.log(colorConfigs);
messages.forEach((message, index, arr) => {
const prevHeader = index > 0 ? arr[index - 1].header : "";
const align = selves && selves.contains(message.header) ? "right" : "left";
const continued = message.header === prevHeader;
this.createChatBubble(continued ? "" : message.header, prevHeader, message.body, message.subtext, align, el, continued, colorConfigs, formatConfigs);
});
});
this.registerMarkdownCodeBlockProcessor("chat", (source, el, _) => {
const rawLines = source.split("\n").filter((line) => ChatPatterns.joined.test(line.trim()));
const lines = rawLines.map((rawLine) => rawLine.trim());
const formatConfigs = new Map();
const colorConfigs = new Map();
for (const line of lines) {
if (ChatPatterns.format.test(line)) {
const configs = line.replace("{", "").replace("}", "").split(",").map((l) => l.trim());
for (const config of configs) {
const [k, v] = config.split("=").map((c) => c.trim());
if (Object.keys(CONFIGS).contains(k) && CONFIGS[k].contains(v))
formatConfigs.set(k, v);
}
} else if (ChatPatterns.colors.test(line)) {
const configs = line.replace("[", "").replace("]", "").split(",").map((l) => l.trim());
for (const config of configs) {
const [k, v] = config.split("=").map((c) => c.trim());
if (k.length > 0 && COLORS.contains(v))
colorConfigs.set(k, v);
}
}
}
let continuedCount = 0;
for (let index = 0; index < lines.length; index++) {
const line = lines[index].trim();
if (ChatPatterns.comment.test(line)) {
el.createEl("p", { text: line.substring(1).trim(), cls: ["chat-view-comment"] });
} else if (line === "...") {
const delimiter = el.createDiv({ cls: ["delimiter"] });
for (let i = 0; i < 3; i++)
delimiter.createDiv({ cls: ["dot"] });
} else if (ChatPatterns.message.test(line)) {
const components = line.substring(1).split("|");
if (components.length > 0) {
const first = components[0];
const header = components.length > 1 ? first.trim() : "";
const message = components.length > 1 ? components[1].trim() : first.trim();
const subtext = components.length > 2 ? components[2].trim() : "";
const continued = index > 0 && line.charAt(0) === lines[index - 1].charAt(0) && header === "";
let prevHeader = "";
if (continued) {
continuedCount++;
const prevComponents = lines[index - continuedCount].trim().substring(1).split("|");
prevHeader = prevComponents[0].length > 1 ? prevComponents[0].trim() : "";
} else {
continuedCount = 0;
}
this.createChatBubble(header, prevHeader, message, subtext, KEYMAP[line.charAt(0)], el, continued, colorConfigs, formatConfigs);
}
}
}
});
});
}
createChatBubble(header, prevHeader, message, subtext, align, element, continued, colorConfigs, formatConfigs) {
const marginClass = continued ? "chat-view-small-vertical-margin" : "chat-view-default-vertical-margin";
const colorConfigClass = `chat-view-${colorConfigs.get(continued ? prevHeader : header)}`;
const widthClass = formatConfigs.has("mw") ? `chat-view-max-width-${formatConfigs.get("mw")}` : import_obsidian.Platform.isMobile ? "chat-view-mobile-width" : "chat-view-desktop-width";
const modeClass = `chat-view-bubble-mode-${formatConfigs.has("mode") ? formatConfigs.get("mode") : "default"}`;
const headerEl = formatConfigs.has("header") ? formatConfigs.get("header") : "h4";
const bubble = element.createDiv({
cls: ["chat-view-bubble", `chat-view-align-${align}`, marginClass, colorConfigClass, widthClass, modeClass]
});
if (header.length > 0)
bubble.createEl(headerEl, { text: header, cls: ["chat-view-header"] });
if (message.length > 0)
bubble.createEl("p", { text: message, cls: ["chat-view-message"] });
if (subtext.length > 0)
bubble.createEl("sub", { text: subtext, cls: ["chat-view-subtext"] });
}
};