Initial commit: Task Progress Bar plugin for Obsidian

This commit is contained in:
Hoang Nam 2025-03-16 16:26:27 +07:00
parent 6d09ce3e39
commit 48b7c27b46
5 changed files with 1230 additions and 83 deletions

587
main.ts
View file

@ -1,85 +1,278 @@
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
import { App, Plugin, PluginSettingTab, Setting, WorkspaceLeaf, TFile, MarkdownView, ItemView, Editor, MarkdownPostProcessorContext, debounce, Notice } from 'obsidian';
// Remember to rename these classes and interfaces!
// Định nghĩa interface cho DataviewAPI
interface DataviewApi {
executeJs(code: string, container: HTMLElement, sourcePath?: string): Promise<any>;
page(path: string): any;
pages(source: string): any[];
// Không sử dụng eval vì có thể không tồn tại trong một số phiên bản Dataview
}
interface MyPluginSettings {
// Định nghĩa interface cho window object để truy cập Dataview plugin
declare global {
interface Window {
DataviewAPI?: DataviewApi;
}
}
// Hàm helper để lấy Dataview API
function getDataviewAPI(app: App): DataviewApi | null {
// Cách 1: Thông qua window object
// @ts-ignore
if (window.DataviewAPI) {
return window.DataviewAPI;
}
// Cách 2: Thông qua app.plugins
// @ts-ignore
const dataviewPlugin = app.plugins?.plugins?.dataview;
if (dataviewPlugin && dataviewPlugin.api) {
return dataviewPlugin.api;
}
// Cách 3: Kiểm tra xem plugin có được enable không
// @ts-ignore
if (app.plugins.enabledPlugins.has('dataview')) {
console.log('Dataview plugin is enabled but API is not available yet');
return null;
}
console.log('Dataview plugin is not enabled');
return null;
}
interface TaskProgressBarSettings {
mySetting: string;
showDebugInfo: boolean;
}
const DEFAULT_SETTINGS: MyPluginSettings = {
mySetting: 'default'
const DEFAULT_SETTINGS: TaskProgressBarSettings = {
mySetting: 'default',
showDebugInfo: false
}
export default class MyPlugin extends Plugin {
settings: MyPluginSettings;
export default class TaskProgressBarPlugin extends Plugin {
settings: TaskProgressBarSettings;
dvAPI: DataviewApi | null = null;
private sidebarView: TaskProgressBarView | null = null;
private lastActiveFile: TFile | null = null;
private lastFileContent: string = '';
private dataviewCheckInterval: number | null = null;
async onload() {
await this.loadSettings();
// This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
// Called when the user clicks the icon.
new Notice('This is a notice!');
});
// Perform additional things with the ribbon
ribbonIconEl.addClass('my-plugin-ribbon-class');
// Register view type for the sidebar
this.registerView(
'progress-tracker',
(leaf) => (this.sidebarView = new TaskProgressBarView(leaf, this))
);
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
const statusBarItemEl = this.addStatusBarItem();
statusBarItemEl.setText('Status Bar Text');
// Add icon to the left sidebar
this.addRibbonIcon('bar-chart-horizontal', 'Progress Tracker', () => {
this.activateView();
});
// This adds a simple command that can be triggered anywhere
this.addCommand({
id: 'open-sample-modal-simple',
name: 'Open sample modal (simple)',
callback: () => {
new SampleModal(this.app).open();
}
});
// This adds an editor command that can perform some operation on the current editor instance
this.addCommand({
id: 'sample-editor-command',
name: 'Sample editor command',
editorCallback: (editor: Editor, view: MarkdownView) => {
console.log(editor.getSelection());
editor.replaceSelection('Sample Editor Command');
}
});
// This adds a complex command that can check whether the current state of the app allows execution of the command
this.addCommand({
id: 'open-sample-modal-complex',
name: 'Open sample modal (complex)',
checkCallback: (checking: boolean) => {
// Conditions to check
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
if (markdownView) {
// If checking is true, we're simply "checking" if the command can be run.
// If checking is false, then we want to actually perform the operation.
if (!checking) {
new SampleModal(this.app).open();
// Add settings tab
this.addSettingTab(new TaskProgressBarSettingTab(this.app, this));
// Kiểm tra Dataview API và thiết lập interval để kiểm tra lại nếu chưa có
this.checkDataviewAPI();
// Register event to update progress bar when file changes
this.registerEvent(
this.app.workspace.on('file-open', (file) => {
if (file) {
this.lastActiveFile = file;
this.updateLastFileContent(file);
if (this.sidebarView) {
this.sidebarView.updateProgressBar(file);
}
}
})
);
// This command will only show up in Command Palette when the check function returns true
return true;
// Register event to update progress bar when editor changes
this.registerEvent(
this.app.workspace.on('editor-change', debounce(async (editor, view) => {
if (view instanceof MarkdownView && this.sidebarView) {
// Lấy nội dung hiện tại của editor
const content = editor.getValue();
// Kiểm tra xem nội dung có chứa task hay không
if (content.includes('- [') || content.includes('- [ ]') || content.includes('- [x]')) {
// Cập nhật ngay lập tức
if (this.lastActiveFile) {
// Cập nhật nội dung file cuối cùng trước khi kiểm tra thay đổi
this.lastActiveFile = view.file;
// Cập nhật thanh tiến trình ngay lập tức
this.sidebarView.updateProgressBar(view.file, content);
// Sau đó mới cập nhật nội dung file cuối cùng
this.lastFileContent = content;
}
}
}
}, 200)) // Giảm debounce xuống 200ms để phản ứng nhanh hơn
);
// Lắng nghe sự kiện keydown để phát hiện khi người dùng nhập task mới hoặc check/uncheck task
this.registerDomEvent(document, 'keydown', (evt: KeyboardEvent) => {
// Kiểm tra xem có đang trong editor không
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
if (activeView && activeView.getMode() === 'source') {
// Cập nhật ngay lập tức khi nhấn các phím liên quan đến task
if (['Enter', 'Space', ']', 'x', 'X', 'Backspace', 'Delete'].includes(evt.key)) {
// Cập nhật ngay lập tức
setTimeout(() => {
const content = activeView.editor.getValue();
if (content.includes('- [') || content.includes('- [ ]') || content.includes('- [x]')) {
this.lastActiveFile = activeView.file;
// Cập nhật thanh tiến trình ngay lập tức
if (this.sidebarView) {
this.sidebarView.updateProgressBar(activeView.file, content);
}
// Sau đó mới cập nhật nội dung file cuối cùng
this.lastFileContent = content;
}
}, 10); // Giảm thời gian chờ xuống 10ms
}
}
});
// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new SampleSettingTab(this.app, this));
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
// Using this function will automatically remove the event listener when this plugin is disabled.
// Lắng nghe sự kiện click trong editor để phát hiện khi task được check/uncheck
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
console.log('click', evt);
const target = evt.target as HTMLElement;
// Kiểm tra xem click có phải vào checkbox của task không
if (target && target.tagName === 'INPUT' && target.classList.contains('task-list-item-checkbox')) {
// Đợi một chút để Obsidian cập nhật trạng thái task trong file
setTimeout(async () => {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile && this.sidebarView) {
// Đọc nội dung file hiện tại
const content = await this.app.vault.read(activeFile);
// Cập nhật thanh tiến trình ngay lập tức
this.lastActiveFile = activeFile;
this.sidebarView.updateProgressBar(activeFile, content);
// Sau đó mới cập nhật nội dung file cuối cùng
this.lastFileContent = content;
}
}, 50); // Giảm thời gian chờ xuống 50ms
}
});
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
// Activate view when plugin loads - đợi một chút để Obsidian khởi động hoàn toàn
setTimeout(() => {
this.activateView();
}, 1000);
}
// Kiểm tra Dataview API và thiết lập interval để kiểm tra lại nếu chưa có
checkDataviewAPI() {
// Kiểm tra ngay lập tức
this.dvAPI = getDataviewAPI(this.app);
// Nếu không tìm thấy, thiết lập interval để kiểm tra lại
if (!this.dvAPI) {
this.dataviewCheckInterval = window.setInterval(() => {
this.dvAPI = getDataviewAPI(this.app);
if (this.dvAPI) {
console.log('Dataview API found');
// Nếu tìm thấy, xóa interval
if (this.dataviewCheckInterval) {
clearInterval(this.dataviewCheckInterval);
this.dataviewCheckInterval = null;
}
// Cập nhật sidebar nếu đang mở
if (this.sidebarView && this.lastActiveFile) {
this.sidebarView.updateProgressBar(this.lastActiveFile);
}
}
}, 2000); // Kiểm tra mỗi 2 giây
}
}
// Kiểm tra xem trạng thái task có thay đổi không
hasTaskStatusChanged(newContent: string): boolean {
// Nếu chưa có nội dung cũ, coi như đã thay đổi
if (!this.lastFileContent) return true;
// Đếm số lượng task hoàn thành trong nội dung cũ và mới
// Sử dụng regex chính xác hơn để phát hiện task
const oldCompletedTasks = (this.lastFileContent.match(/- \[x\]/gi) || []).length;
const newCompletedTasks = (newContent.match(/- \[x\]/gi) || []).length;
// Đếm tổng số task trong nội dung cũ và mới
// Sử dụng regex chính xác hơn để phát hiện task chưa hoàn thành
const oldIncompleteTasks = (this.lastFileContent.match(/- \[ \]/g) || []).length;
const newIncompleteTasks = (newContent.match(/- \[ \]/g) || []).length;
const oldTotalTasks = oldIncompleteTasks + oldCompletedTasks;
const newTotalTasks = newIncompleteTasks + newCompletedTasks;
// Nếu số lượng task hoàn thành hoặc tổng số task thay đổi, coi như đã thay đổi
return oldCompletedTasks !== newCompletedTasks || oldTotalTasks !== newTotalTasks;
}
// Cập nhật nội dung file cuối cùng
async updateLastFileContent(file: TFile) {
if (file) {
this.lastFileContent = await this.app.vault.read(file);
}
}
async activateView() {
try {
const { workspace } = this.app;
// If view already exists in leaves, show it
const leaves = workspace.getLeavesOfType('progress-tracker');
if (leaves.length > 0) {
workspace.revealLeaf(leaves[0]);
return;
}
// Otherwise, create a new leaf in the left sidebar
// Kiểm tra xem workspace đã sẵn sàng chưa
if (!workspace.leftSplit) {
console.log('Workspace not ready yet, retrying in 500ms');
setTimeout(() => this.activateView(), 500);
return;
}
// Sử dụng getLeaf thay vì createLeaf
const leaf = workspace.getLeftLeaf(false);
if (leaf) {
await leaf.setViewState({
type: 'progress-tracker',
active: true,
});
// Reveal the leaf
workspace.revealLeaf(leaf);
}
} catch (error) {
console.error('Error activating view:', error);
new Notice('Error activating Task Progress Bar view. Please try again later.');
}
}
onunload() {
// Xóa interval nếu có
if (this.dataviewCheckInterval) {
clearInterval(this.dataviewCheckInterval);
this.dataviewCheckInterval = null;
}
// Detach the view when plugin unloads
this.app.workspace.detachLeavesOfType('progress-tracker');
}
async loadSettings() {
@ -91,44 +284,292 @@ export default class MyPlugin extends Plugin {
}
}
class SampleModal extends Modal {
constructor(app: App) {
super(app);
class TaskProgressBarView extends ItemView {
plugin: TaskProgressBarPlugin;
currentFile: TFile | null = null;
isVisible: boolean = false;
lastUpdateTime: number = 0;
constructor(leaf: WorkspaceLeaf, plugin: TaskProgressBarPlugin) {
super(leaf);
this.plugin = plugin;
}
onOpen() {
const {contentEl} = this;
contentEl.setText('Woah!');
getViewType(): string {
return 'progress-tracker';
}
onClose() {
const {contentEl} = this;
contentEl.empty();
getDisplayText(): string {
return 'Task Progress Bar';
}
getIcon(): string {
return 'bar-chart-horizontal';
}
async onOpen() {
this.isVisible = true;
const container = this.containerEl.children[1];
container.empty();
container.createEl('h4', { text: 'Task Progress' });
// Create progress container
const progressContainer = container.createDiv({ cls: 'task-progress-container' });
// Update with current file if available
const currentFile = this.app.workspace.getActiveFile();
if (currentFile) {
this.updateProgressBar(currentFile);
} else {
// Hiển thị thông báo nếu không có file nào đang mở
progressContainer.createEl('p', {
text: 'No file is currently open. Open a markdown file to see the progress bar.'
});
}
}
async updateProgressBar(file: TFile | null, content?: string) {
if (!file) return;
// Tránh cập nhật quá nhanh
const now = Date.now();
if (now - this.lastUpdateTime < 100) return; // Giảm thời gian chờ xuống 100ms
this.lastUpdateTime = now;
this.currentFile = file;
const container = this.containerEl.children[1];
const progressContainer = container.querySelector('.task-progress-container') as HTMLElement;
if (!progressContainer) return;
// Thêm class để hiển thị animation
progressContainer.classList.add('updating');
// Cập nhật ngay lập tức nếu có nội dung được cung cấp
if (content) {
this.updateProgressBarContentWithString(content, progressContainer, file);
// Xóa class sau khi cập nhật xong
setTimeout(() => {
progressContainer.classList.remove('updating');
}, 300);
} else {
// Nếu không có nội dung, đọc từ file
setTimeout(async () => {
// Đọc nội dung file
const fileContent = await this.plugin.app.vault.read(file);
// Cập nhật với nội dung đọc được
this.updateProgressBarContentWithString(fileContent, progressContainer, file);
// Xóa class sau khi cập nhật xong
setTimeout(() => {
progressContainer.classList.remove('updating');
}, 300);
}, 50);
}
}
// Phương thức mới để cập nhật với nội dung string trực tiếp
async updateProgressBarContentWithString(content: string, progressContainer: HTMLElement, file: TFile) {
progressContainer.empty();
// Get Dataview API
const dvAPI = this.plugin.dvAPI;
if (!dvAPI) {
// Vẫn hiển thị thanh tiến trình ngay cả khi không có Dataview API
try {
// Tạo thanh tiến trình trực tiếp từ nội dung
this.createProgressBarFromString(progressContainer, content, file);
// Thêm thông tin về thời gian cập nhật
const updateInfo = progressContainer.createDiv({ cls: 'update-info' });
updateInfo.createSpan({
text: `Last updated: ${new Date().toLocaleTimeString()}`,
cls: 'update-time'
});
// Thêm thông báo về Dataview không khả dụng
const dataviewWarning = progressContainer.createDiv({ cls: 'dataview-warning' });
dataviewWarning.createEl('p', {
text: 'Note: Dataview plugin is not available. Some advanced features may be limited.'
});
// Thêm nút để kiểm tra lại Dataview
const checkButton = dataviewWarning.createEl('button', {
text: 'Check for Dataview',
cls: 'mod-cta'
});
checkButton.addEventListener('click', () => {
this.plugin.checkDataviewAPI();
if (this.plugin.dvAPI) {
new Notice('Dataview API found!');
this.updateProgressBar(file);
} else {
new Notice('Dataview API not found. Make sure Dataview plugin is installed and enabled.');
}
});
} catch (error) {
console.error('Error creating progress bar without Dataview:', error);
progressContainer.createEl('p', { text: 'Error creating progress bar' });
}
return;
}
try {
// Tạo thanh tiến trình trực tiếp từ nội dung
this.createProgressBarFromString(progressContainer, content, file);
// Thêm thông tin về thời gian cập nhật
const updateInfo = progressContainer.createDiv({ cls: 'update-info' });
updateInfo.createSpan({
text: `Last updated: ${new Date().toLocaleTimeString()}`,
cls: 'update-time'
});
} catch (error) {
console.error('Error updating progress bar:', error);
progressContainer.createEl('p', { text: 'Error loading progress bar' });
}
}
// Phương thức tạo thanh tiến trình từ nội dung string
async createProgressBarFromString(container: HTMLElement, content: string, file: TFile) {
try {
// Sử dụng regex chính xác hơn để đếm task
const incompleteTasks = (content.match(/- \[ \]/g) || []).length;
const completedTasks = (content.match(/- \[x\]/gi) || []).length; // Thêm cờ 'i' để bắt cả 'x' và 'X'
const totalTasks = incompleteTasks + completedTasks;
if (totalTasks === 0) {
container.createEl('p', { text: 'No tasks found in this file' });
return;
}
const percentage = Math.round((completedTasks / totalTasks) * 100);
// Create percentage text
container.createEl('div', {
text: `${percentage}% Complete`,
cls: 'progress-percentage'
});
// Create progress bar
const progressBarContainer = container.createDiv({ cls: 'progress-bar' });
const progressElement = progressBarContainer.createDiv({ cls: 'progress' });
progressElement.style.width = `${percentage}%`;
// Create stats
const statsContainer = container.createDiv({ cls: 'progress-stats' });
statsContainer.createSpan({ text: `${completedTasks}/${totalTasks} tasks complete` });
statsContainer.createSpan({ text: `${totalTasks - completedTasks} remaining` });
// Hiển thị danh sách các task chưa hoàn thành
if (totalTasks - completedTasks > 0) {
const taskList = container.createEl('ul', { cls: 'task-list' });
// Tìm tất cả các task chưa hoàn thành
const lines = content.split('\n');
for (const line of lines) {
if (line.includes('- [ ]')) {
// Lấy nội dung task (bỏ qua "- [ ]")
const taskContent = line.substring(line.indexOf('- [ ]') + 5).trim();
taskList.createEl('li', { text: taskContent });
}
}
}
// Thêm debug info nếu cần
if (this.plugin.settings.showDebugInfo) {
const debugInfo = container.createDiv({ cls: 'debug-info' });
debugInfo.createEl('p', { text: `Debug Info:` });
debugInfo.createEl('p', { text: `File: ${file.path}` });
debugInfo.createEl('p', { text: `Incomplete tasks: ${incompleteTasks}` });
debugInfo.createEl('p', { text: `Completed tasks: ${completedTasks}` });
debugInfo.createEl('p', { text: `Total tasks: ${totalTasks}` });
debugInfo.createEl('p', { text: `Percentage: ${percentage}%` });
debugInfo.createEl('p', { text: `Update time: ${new Date().toISOString()}` });
}
} catch (error) {
console.error('Error creating progress bar from string:', error);
container.createEl('p', { text: 'Error creating progress bar' });
}
}
async onClose() {
this.isVisible = false;
}
}
class SampleSettingTab extends PluginSettingTab {
plugin: MyPlugin;
class TaskProgressBarSettingTab extends PluginSettingTab {
plugin: TaskProgressBarPlugin;
constructor(app: App, plugin: MyPlugin) {
constructor(app: App, plugin: TaskProgressBarPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const {containerEl} = this;
const { containerEl } = this;
containerEl.empty();
containerEl.createEl('h2', { text: 'Task Progress Bar Settings' });
// Thêm thông tin về trạng thái Dataview
const dataviewStatus = containerEl.createDiv({ cls: 'dataview-status' });
if (this.plugin.dvAPI) {
dataviewStatus.createEl('p', {
text: '✅ Dataview API is available',
cls: 'dataview-available'
});
} else {
dataviewStatus.createEl('p', {
text: '❌ Dataview API is not available',
cls: 'dataview-unavailable'
});
// Thêm nút để kiểm tra lại Dataview
const checkButton = dataviewStatus.createEl('button', {
text: 'Check for Dataview',
cls: 'mod-cta'
});
checkButton.addEventListener('click', () => {
this.plugin.checkDataviewAPI();
if (this.plugin.dvAPI) {
new Notice('Dataview API found!');
this.display(); // Refresh settings tab
} else {
new Notice('Dataview API not found. Make sure Dataview plugin is installed and enabled.');
}
});
}
new Setting(containerEl)
.setName('Setting #1')
.setDesc('It\'s a secret')
.setName('Setting')
.setDesc('Description of the setting')
.addText(text => text
.setPlaceholder('Enter your secret')
.setPlaceholder('Enter your setting')
.setValue(this.plugin.settings.mySetting)
.onChange(async (value) => {
this.plugin.settings.mySetting = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Show Debug Info')
.setDesc('Show debug information in the sidebar to help troubleshoot task counting issues')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.showDebugInfo)
.onChange(async (value) => {
this.plugin.settings.showDebugInfo = value;
await this.plugin.saveSettings();
// Cập nhật sidebar nếu đang mở - sử dụng phương thức public
const currentFile = this.app.workspace.getActiveFile();
if (currentFile) {
// Sử dụng phương thức public để cập nhật UI
this.plugin.checkDataviewAPI();
}
}));
}
}

View file

@ -1,11 +1,11 @@
{
"id": "sample-plugin",
"name": "Sample Plugin",
"id": "progress-tracker",
"name": "ProgressTracker",
"version": "1.0.0",
"minAppVersion": "0.15.0",
"description": "Demonstrates some of the capabilities of the Obsidian API.",
"author": "Obsidian",
"authorUrl": "https://obsidian.md",
"fundingUrl": "https://obsidian.md/pricing",
"description": "Track task completion with a visual progress bar in your sidebar",
"author": "VN",
"authorUrl": "https://wpmasterynow.com",
"fundingUrl": "https://wpmasterynow.com",
"isDesktopOnly": false
}

View file

@ -1,15 +1,15 @@
{
"name": "obsidian-sample-plugin",
"name": "progress-tracker",
"version": "1.0.0",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"description": "Track task completion with a visual progress bar in your sidebar",
"main": "main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json"
},
"keywords": [],
"author": "",
"keywords": ["obsidian", "dataview", "progress", "task"],
"author": "VN",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",

View file

@ -6,3 +6,192 @@ available in the app when your plugin is enabled.
If your plugin does not need CSS, delete this file.
*/
/*
* Task Progress Bar Styles
*/
.task-progress-container {
padding: 10px;
margin-top: 10px;
transition: opacity 0.2s ease;
}
.task-progress-container.updating {
opacity: 0.7;
}
.task-progress-container .progress-bar {
width: 100%;
height: 10px;
background-color: var(--background-secondary);
border-radius: 5px;
margin: 10px 0;
overflow: hidden;
}
.task-progress-container .progress-bar .progress {
height: 100%;
background-color: var(--interactive-accent);
border-radius: 5px;
transition: width 0.3s ease;
}
.task-progress-container .progress-stats {
display: flex;
justify-content: space-between;
font-size: 0.8em;
color: var(--text-muted);
margin-bottom: 10px;
}
.task-progress-container pre {
font-size: 0.8em;
padding: 8px;
background-color: var(--background-secondary);
border-radius: 4px;
overflow-x: auto;
}
/* Ensure dataview elements display properly in the sidebar */
.task-progress-container .dataview-result-table-wrapper {
max-width: 100%;
overflow-x: auto;
}
.task-progress-container .dataview-result-table {
width: 100%;
font-size: 0.85em;
}
/* Style for the progress percentage text */
.task-progress-container .progress-percentage {
font-weight: bold;
color: var(--text-normal);
text-align: center;
margin-bottom: 5px;
font-size: 1.2em;
}
/* Style for source info */
.task-progress-container .source-info {
font-size: 0.75em;
color: var(--text-muted);
margin-top: 10px;
font-style: italic;
}
/* Style for update info */
.task-progress-container .update-info {
font-size: 0.7em;
color: var(--text-muted);
text-align: right;
margin-top: 10px;
border-top: 1px solid var(--background-modifier-border);
padding-top: 5px;
}
.task-progress-container .update-time {
font-style: italic;
}
/* Animation for updates */
@keyframes highlight {
0% { background-color: transparent; }
30% { background-color: var(--background-modifier-success); }
100% { background-color: transparent; }
}
.task-progress-container.updated .progress-bar {
animation: highlight 1.5s ease;
}
/* Styles for task list in sidebar */
.task-progress-container ul.task-list {
padding-left: 15px;
margin: 5px 0;
max-height: 150px;
overflow-y: auto;
border-left: 2px solid var(--background-modifier-border);
}
.task-progress-container ul.task-list li {
font-size: 0.85em;
margin-bottom: 3px;
list-style-type: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Styles for Dataview status in settings */
.dataview-status {
margin: 15px 0;
padding: 10px;
border-radius: 5px;
background-color: var(--background-secondary);
}
.dataview-status .dataview-available {
color: var(--text-success);
font-weight: bold;
}
.dataview-status .dataview-unavailable {
color: var(--text-error);
font-weight: bold;
margin-bottom: 10px;
}
.dataview-status button {
margin-top: 5px;
}
/* Styles for Dataview warning in sidebar */
.dataview-warning {
margin-top: 15px;
padding: 8px;
border-radius: 4px;
background-color: var(--background-modifier-error-rgb);
background-color: rgba(var(--background-modifier-error-rgb), 0.1);
border-left: 3px solid var(--text-error);
font-size: 0.8em;
}
.dataview-warning p {
margin: 0 0 8px 0;
color: var(--text-muted);
}
.dataview-warning button {
font-size: 0.9em;
padding: 2px 8px;
}
/* Styles for debug info */
.debug-info {
margin-top: 15px;
padding: 8px;
border-radius: 4px;
background-color: var(--background-secondary);
border-left: 3px solid var(--text-accent);
font-size: 0.75em;
color: var(--text-muted);
}
.debug-info p {
margin: 0 0 4px 0;
font-family: var(--font-monospace);
}
/* Responsive design for small screens */
@media (max-width: 600px) {
.task-progress-container .progress-stats {
flex-direction: column;
align-items: center;
}
.task-progress-container .progress-stats span:first-child {
margin-bottom: 5px;
}
}

517
yarn.lock Normal file
View file

@ -0,0 +1,517 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@esbuild/android-arm64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz#35d045f69c9b4cf3f8efcd1ced24a560213d3346"
integrity sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==
"@esbuild/android-arm@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.3.tgz#4986d26306a7440078d42b3bf580d186ef714286"
integrity sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==
"@esbuild/android-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.3.tgz#a1928cd681e4055103384103c8bd34df7b9c7b19"
integrity sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==
"@esbuild/darwin-arm64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz#e4af2b392e5606a4808d3a78a99d38c27af39f1d"
integrity sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==
"@esbuild/darwin-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz#cbcbfb32c8d5c86953f215b48384287530c5a38e"
integrity sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==
"@esbuild/freebsd-arm64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz#90ec1755abca4c3ffe1ad10819cd9d31deddcb89"
integrity sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==
"@esbuild/freebsd-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz#8760eedc466af253c3ed0dfa2940d0e59b8b0895"
integrity sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==
"@esbuild/linux-arm64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz#13916fc8873115d7d546656e19037267b12d4567"
integrity sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==
"@esbuild/linux-arm@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz#15f876d127b244635ddc09eaaa65ae97bc472a63"
integrity sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==
"@esbuild/linux-ia32@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz#6691f02555d45b698195c81c9070ab4e521ef005"
integrity sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==
"@esbuild/linux-loong64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz#f77ef657f222d8b3a8fbd530a09e40976c458d48"
integrity sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==
"@esbuild/linux-mips64el@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz#fa38833cfc8bfaadaa12b243257fe6d19d0f6f79"
integrity sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==
"@esbuild/linux-ppc64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz#c157a602b627c90d174743e4b0dfb7630b101dbf"
integrity sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==
"@esbuild/linux-riscv64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz#7bf79614bd544bd932839b1fcff6cf1f8f6bdf1a"
integrity sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==
"@esbuild/linux-s390x@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz#6bb50c5a2613d31ce1137fe5c249ecadbecccdea"
integrity sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==
"@esbuild/linux-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz#aa140d99f0d9e0af388024823bfe4558d73fbbf9"
integrity sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==
"@esbuild/netbsd-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz#b6ae9948b03e4c95dc581c68358fb61d9d12a625"
integrity sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==
"@esbuild/openbsd-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz#cda007233e211fc9154324bfa460540cfc469408"
integrity sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==
"@esbuild/sunos-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz#f1385b092000c662d360775f3fad80943d2169c4"
integrity sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==
"@esbuild/win32-arm64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz#14e9dd9b1b55aa991f80c120fef0c4492d918801"
integrity sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==
"@esbuild/win32-ia32@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz#de584423513d13304a6925e01233499a37a4e075"
integrity sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==
"@esbuild/win32-x64@0.17.3":
version "0.17.3"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz#2f69ea6b37031b0d1715dd2da832a8ae5eb36e74"
integrity sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.3":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@types/codemirror@5.60.8":
version "5.60.8"
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-5.60.8.tgz#b647d04b470e8e1836dd84b2879988fc55c9de68"
integrity sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==
dependencies:
"@types/tern" "*"
"@types/estree@*":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
"@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/node@^16.11.6":
version "16.18.126"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.126.tgz#27875faa2926c0f475b39a8bb1e546c0176f8d4b"
integrity sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==
"@types/tern@*":
version "0.23.9"
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.9.tgz#6f6093a4a9af3e6bb8dde528e024924d196b367c"
integrity sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==
dependencies:
"@types/estree" "*"
"@typescript-eslint/eslint-plugin@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.29.0.tgz#c67794d2b0fd0b4a47f50266088acdc52a08aab6"
integrity sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==
dependencies:
"@typescript-eslint/scope-manager" "5.29.0"
"@typescript-eslint/type-utils" "5.29.0"
"@typescript-eslint/utils" "5.29.0"
debug "^4.3.4"
functional-red-black-tree "^1.0.1"
ignore "^5.2.0"
regexpp "^3.2.0"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.29.0.tgz#41314b195b34d44ff38220caa55f3f93cfca43cf"
integrity sha512-ruKWTv+x0OOxbzIw9nW5oWlUopvP/IQDjB5ZqmTglLIoDTctLlAJpAQFpNPJP/ZI7hTT9sARBosEfaKbcFuECw==
dependencies:
"@typescript-eslint/scope-manager" "5.29.0"
"@typescript-eslint/types" "5.29.0"
"@typescript-eslint/typescript-estree" "5.29.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.29.0.tgz#2a6a32e3416cb133e9af8dcf54bf077a916aeed3"
integrity sha512-etbXUT0FygFi2ihcxDZjz21LtC+Eps9V2xVx09zFoN44RRHPrkMflidGMI+2dUs821zR1tDS6Oc9IXxIjOUZwA==
dependencies:
"@typescript-eslint/types" "5.29.0"
"@typescript-eslint/visitor-keys" "5.29.0"
"@typescript-eslint/type-utils@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.29.0.tgz#241918001d164044020b37d26d5b9f4e37cc3d5d"
integrity sha512-JK6bAaaiJozbox3K220VRfCzLa9n0ib/J+FHIwnaV3Enw/TO267qe0pM1b1QrrEuy6xun374XEAsRlA86JJnyg==
dependencies:
"@typescript-eslint/utils" "5.29.0"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.29.0.tgz#7861d3d288c031703b2d97bc113696b4d8c19aab"
integrity sha512-X99VbqvAXOMdVyfFmksMy3u8p8yoRGITgU1joBJPzeYa0rhdf5ok9S56/itRoUSh99fiDoMtarSIJXo7H/SnOg==
"@typescript-eslint/typescript-estree@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.29.0.tgz#e83d19aa7fd2e74616aab2f25dfbe4de4f0b5577"
integrity sha512-mQvSUJ/JjGBdvo+1LwC+GY2XmSYjK1nAaVw2emp/E61wEVYEyibRHCqm1I1vEKbXCpUKuW4G7u9ZCaZhJbLoNQ==
dependencies:
"@typescript-eslint/types" "5.29.0"
"@typescript-eslint/visitor-keys" "5.29.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.29.0.tgz#775046effd5019667bd086bcf326acbe32cd0082"
integrity sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.29.0"
"@typescript-eslint/types" "5.29.0"
"@typescript-eslint/typescript-estree" "5.29.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/visitor-keys@5.29.0":
version "5.29.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz#7a4749fa7ef5160c44a451bf060ac1dc6dfb77ee"
integrity sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==
dependencies:
"@typescript-eslint/types" "5.29.0"
eslint-visitor-keys "^3.3.0"
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
builtin-modules@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
debug@^4.3.4:
version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
dependencies:
path-type "^4.0.0"
esbuild@0.17.3:
version "0.17.3"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.3.tgz#d9aa02a3bc441ed35f9569cd9505812ae3fcae61"
integrity sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==
optionalDependencies:
"@esbuild/android-arm" "0.17.3"
"@esbuild/android-arm64" "0.17.3"
"@esbuild/android-x64" "0.17.3"
"@esbuild/darwin-arm64" "0.17.3"
"@esbuild/darwin-x64" "0.17.3"
"@esbuild/freebsd-arm64" "0.17.3"
"@esbuild/freebsd-x64" "0.17.3"
"@esbuild/linux-arm" "0.17.3"
"@esbuild/linux-arm64" "0.17.3"
"@esbuild/linux-ia32" "0.17.3"
"@esbuild/linux-loong64" "0.17.3"
"@esbuild/linux-mips64el" "0.17.3"
"@esbuild/linux-ppc64" "0.17.3"
"@esbuild/linux-riscv64" "0.17.3"
"@esbuild/linux-s390x" "0.17.3"
"@esbuild/linux-x64" "0.17.3"
"@esbuild/netbsd-x64" "0.17.3"
"@esbuild/openbsd-x64" "0.17.3"
"@esbuild/sunos-x64" "0.17.3"
"@esbuild/win32-arm64" "0.17.3"
"@esbuild/win32-ia32" "0.17.3"
"@esbuild/win32-x64" "0.17.3"
eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
dependencies:
eslint-visitor-keys "^2.0.0"
eslint-visitor-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint-visitor-keys@^3.3.0:
version "3.4.3"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
fast-glob@^3.2.9:
version "3.3.3"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.2"
merge2 "^1.3.0"
micromatch "^4.0.8"
fastq@^1.6.0:
version "1.19.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5"
integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==
dependencies:
reusify "^1.0.4"
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==
glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
globby@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
fast-glob "^3.2.9"
ignore "^5.2.0"
merge2 "^1.4.1"
slash "^3.0.0"
ignore@^5.2.0:
version "5.3.2"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-glob@^4.0.1, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.3"
picomatch "^2.3.1"
moment@2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
obsidian@latest:
version "1.8.7"
resolved "https://registry.yarnpkg.com/obsidian/-/obsidian-1.8.7.tgz#601e9ea1724289effa4c9bb3b4e20d327263634f"
integrity sha512-h4bWwNFAGRXlMlMAzdEiIM2ppTGlrh7uGOJS6w4gClrsjc+ei/3YAtU2VdFUlCiPuTHpY4aBpFJJW75S1Tl/JA==
dependencies:
"@types/codemirror" "5.60.8"
moment "2.29.4"
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
regexpp@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
reusify@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f"
integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
queue-microtask "^1.2.2"
semver@^7.3.7:
version "7.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
tslib@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
typescript@4.7.4:
version "4.7.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==