/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/main.ts var main_exports = {}; __export(main_exports, { MetadataInputModal: () => MetadataInputModal, default: () => TimelinePlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian6 = require("obsidian"); // src/i18n.ts var zhCN = { settings: { resetSettings: "\u91CD\u7F6E\u8BBE\u7F6E", resetSettingsDesc: "\u5C06\u6240\u6709\u8BBE\u7F6E\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C", resetSettingsButton: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C", lineWidth: "\u65F6\u95F4\u8F74\u7EBF\u5BBD\u5EA6", lineWidthDesc: "\u8BBE\u7F6E\u4E3B\u65F6\u95F4\u8F74\u7EBF\u7684\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09", lineColor: "\u65F6\u95F4\u8F74\u7EBF\u989C\u8272", lineColorDesc: "\u8BBE\u7F6E\u65F6\u95F4\u8F74\u7EBF\u7684\u989C\u8272", colorPickerPlaceholder: "\u70B9\u51FB\u5DE6\u4FA7\u8272\u76D8\u9009\u62E9\u989C\u8272", itemSpacing: "\u9879\u76EE\u95F4\u8DDD", itemSpacingDesc: "\u8BBE\u7F6E\u65F6\u95F4\u8F74\u9879\u76EE\u4E4B\u95F4\u7684\u95F4\u8DDD\uFF08\u50CF\u7D20\uFF09", cardBackground: "\u5361\u7247\u80CC\u666F\u8272", cardBackgroundDesc: "\u8BBE\u7F6E\u5185\u5BB9\u5361\u7247\u7684\u80CC\u666F\u989C\u8272", cardTextColor: "\u5361\u7247\u6587\u5B57\u989C\u8272", cardTextColorDesc: "\u8BBE\u7F6E\u666E\u901A\u4E8B\u4EF6\u5361\u7247\u7684\u6587\u5B57\u989C\u8272", cardBorderColor: "\u5361\u7247\u8FB9\u6846\u989C\u8272", cardBorderColorDesc: "\u8BBE\u7F6E\u666E\u901A\u4E8B\u4EF6\u5361\u7247\u7684\u8FB9\u6846\u989C\u8272", milestoneCardBackground: "\u91CC\u7A0B\u7891\u5361\u7247\u80CC\u666F\u8272", milestoneCardBackgroundDesc: "\u8BBE\u7F6E\u91CC\u7A0B\u7891\u4E8B\u4EF6\u5361\u7247\u7684\u80CC\u666F\u989C\u8272", milestoneCardTextColor: "\u91CC\u7A0B\u7891\u5361\u7247\u6587\u5B57\u989C\u8272", milestoneCardTextColorDesc: "\u8BBE\u7F6E\u91CC\u7A0B\u7891\u4E8B\u4EF6\u5361\u7247\u7684\u6587\u5B57\u989C\u8272", milestoneCardBorderColor: "\u91CC\u7A0B\u7891\u5361\u7247\u8FB9\u6846\u989C\u8272", milestoneCardBorderColorDesc: "\u8BBE\u7F6E\u91CC\u7A0B\u7891\u4E8B\u4EF6\u5361\u7247\u7684\u8FB9\u6846\u989C\u8272", animationDuration: "\u52A8\u753B\u6301\u7EED\u65F6\u95F4", animationDurationDesc: "\u8BBE\u7F6E\u60AC\u505C\u52A8\u753B\u7684\u6301\u7EED\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09", dateAttribute: "\u65E5\u671F\u5C5E\u6027", dateAttributeDesc: "\u9009\u62E9\u7528\u4E8E\u65F6\u95F4\u8F74\u6392\u5E8F\u7684 frontmatter \u65E5\u671F\u5C5E\u6027\uFF08\u5982\uFF1Acreated, updated, date \u7B49\uFF09", fileNamePrefix: "\u6587\u4EF6\u540D\u524D\u7F00", fileNamePrefixDesc: "\u8BBE\u7F6E\u751F\u6210\u7684\u65F6\u95F4\u8F74\u6587\u4EF6\u540D\u524D\u7F00", fileNameSuffix: "\u6587\u4EF6\u540D\u540E\u7F00", fileNameSuffixDesc: "\u8BBE\u7F6E\u751F\u6210\u7684\u65F6\u95F4\u8F74\u6587\u4EF6\u540D\u540E\u7F00", defaultPosition: "\u9ED8\u8BA4\u4F4D\u7F6E", defaultPositionDesc: "\u9009\u62E9\u65F6\u95F4\u8F74\u89C6\u56FE\u5728\u5DE6\u4FA7\u8FD8\u662F\u53F3\u4FA7\u8FB9\u680F\u663E\u793A", leftSidebar: "\u5DE6\u4FA7\u8FB9\u680F", rightSidebar: "\u53F3\u4FA7\u8FB9\u680F", language: "\u8BED\u8A00", languageDesc: "\u9009\u62E9\u63D2\u4EF6\u754C\u9762\u8BED\u8A00", milestoneAttribute: "\u91CC\u7A0B\u7891\u5C5E\u6027", milestoneAttributeDesc: "\u7528\u4E8E\u6807\u8BB0\u91CC\u7A0B\u7891\u4E8B\u4EF6\u7684 frontmatter \u5C5E\u6027\u540D\u79F0\uFF08\u4F8B\u5982\uFF1Amilestone\uFF09", milestoneValue: "\u91CC\u7A0B\u7891\u503C", milestoneValueDesc: "\u91CC\u7A0B\u7891\u5C5E\u6027\u9700\u8981\u5339\u914D\u7684\u503C\uFF08\u7559\u7A7A\u5219\u8868\u793A\u53EA\u8981\u5C5E\u6027\u5B58\u5728\u5373\u53EF\uFF0C\u4F8B\u5982\uFF1Atrue, 1\uFF09" }, commands: { openTimelineView: "\u6253\u5F00\u65F6\u95F4\u8F74\u89C6\u56FE", generateFromFolder: "\u4ECE\u6587\u4EF6\u5939\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE", generateFileFromFolder: "\u4ECE\u6587\u4EF6\u5939\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6", generateFromTag: "\u4ECE\u6807\u7B7E\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE", generateFileFromTag: "\u4ECE\u6807\u7B7E\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6", generateFromFileLinks: "\u4ECE\u5F53\u524D\u6587\u4EF6\u94FE\u63A5\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE", generateFileFromFileLinks: "\u4ECE\u5F53\u524D\u6587\u4EF6\u94FE\u63A5\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6", generateFromMetadata: "\u4ECE\u5143\u6570\u636E\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE", generateFileFromMetadata: "\u4ECE\u5143\u6570\u636E\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6" }, modal: { metadataInputTitle: "\u8F93\u5165\u5143\u6570\u636E\u5B57\u7B26\u4E32", metadataQueryName: "\u5143\u6570\u636E\u67E5\u8BE2", metadataQueryDesc: "\u4F8B\u5982\uFF1Aauthor: - \u6211 \u6216 status: ongoing", metadataInputPlaceholder: "\u8F93\u5165\u5143\u6570\u636E...", submitButton: "\u786E\u5B9A", cancelButton: "\u53D6\u6D88", emptyInputNotice: "\u8BF7\u8F93\u5165\u5143\u6570\u636E\u5B57\u7B26\u4E32" }, errors: { renderFailed: "\u65F6\u95F4\u8F74\u89C6\u56FE\u6E32\u67D3\u5931\u8D25", generateFolderFailed: "\u751F\u6210\u6587\u4EF6\u5939\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519", generateTagFailed: "\u751F\u6210\u6807\u7B7E\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519", generateFileFailed: "\u4ECE\u6587\u4EF6\u94FE\u63A5\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519", noTaggedFiles: "\u6CA1\u6709\u627E\u5230\u5305\u542B\u6807\u7B7E #{tag} \u53CA\u5176\u5B50\u6807\u7B7E\u7684\u6587\u4EF6", noFileLinks: "\u6587\u4EF6 {filename} \u4E2D\u6CA1\u6709\u627E\u5230\u53EF\u7528\u7684\u94FE\u63A5\u6216\u65E5\u671F\u4FE1\u606F", createViewFailed: "\u65E0\u6CD5\u521B\u5EFA\u65F6\u95F4\u8F74\u89C6\u56FE\uFF1A\u8BF7\u68C0\u67E5\u4FA7\u8FB9\u680F\u7A7A\u95F4", noMetadataFiles: "\u6CA1\u6709\u627E\u5230\u4E0E\u5143\u6570\u636E\u67E5\u8BE2 \u201C{query}\u201D \u5339\u914D\u7684\u6587\u4EF6", generateMetadataFailed: "\u4ECE\u5143\u6570\u636E\u751F\u6210\u65F6\u95F4\u8F74\u5931\u8D25" } }; var enUS = { settings: { resetSettings: "Reset Settings", resetSettingsDesc: "Restore all settings to default values", resetSettingsButton: "Reset to Defaults", lineWidth: "Timeline Line Width", lineWidthDesc: "Set the width of the main timeline line (pixels)", lineColor: "Timeline Line Color", lineColorDesc: "Set the color of the timeline line", colorPickerPlaceholder: "Click the color picker on the left", itemSpacing: "Item Spacing", itemSpacingDesc: "Set the spacing between timeline items (pixels)", cardBackground: "Card Background Color", cardBackgroundDesc: "Set the background color of content cards", cardTextColor: "Card Text Color", cardTextColorDesc: "Set the text color of regular event cards", cardBorderColor: "Card Border Color", cardBorderColorDesc: "Set the border color of regular event cards", milestoneCardBackground: "Milestone Card Background", milestoneCardBackgroundDesc: "Set the background color of milestone event cards", milestoneCardTextColor: "Milestone Card Text Color", milestoneCardTextColorDesc: "Set the text color of milestone event cards", milestoneCardBorderColor: "Milestone Card Border Color", milestoneCardBorderColorDesc: "Set the border color of milestone event cards", animationDuration: "Animation Duration", animationDurationDesc: "Set the duration of hover animations (milliseconds)", dateAttribute: "Date Attribute", dateAttributeDesc: "Choose the frontmatter date attribute for timeline sorting (e.g., created, updated, date)", fileNamePrefix: "File Name Prefix", fileNamePrefixDesc: "Set the prefix for generated timeline file names", fileNameSuffix: "File Name Suffix", fileNameSuffixDesc: "Set the suffix for generated timeline file names", defaultPosition: "Default Position", defaultPositionDesc: "Choose whether to display the timeline view in the left or right sidebar", leftSidebar: "Left Sidebar", rightSidebar: "Right Sidebar", language: "Language", languageDesc: "Select plugin interface language", milestoneAttribute: "Milestone Attribute", milestoneAttributeDesc: "The frontmatter attribute name used to mark milestone events (e.g., milestone)", milestoneValue: "Milestone Value", milestoneValueDesc: "The value the milestone attribute needs to match (leave empty to match if the attribute exists, e.g., true, 1)" }, commands: { openTimelineView: "Open Timeline View", generateFromFolder: "Generate Timeline View from any Folder", generateFileFromFolder: "Generate Timeline File from any Folder", generateFromTag: "Generate Timeline View from any Tag", generateFileFromTag: "Generate Timeline File from any Tag", generateFromFileLinks: "Generate Timeline View from Current File Links", generateFileFromFileLinks: "Generate Timeline File from Current File Links", generateFromMetadata: "Generate Timeline View from any Metadata", generateFileFromMetadata: "Generate Timeline File from any Metadata" }, modal: { metadataInputTitle: "Enter Metadata String", metadataQueryName: "Metadata Query", metadataQueryDesc: "e.g., author: - Me or status: ongoing", metadataInputPlaceholder: "Enter metadata...", submitButton: "Submit", cancelButton: "Cancel", emptyInputNotice: "Please enter a metadata string" }, errors: { renderFailed: "Failed to render timeline view", generateFolderFailed: "Error generating folder timeline view", generateTagFailed: "Error generating tag timeline view", generateFileFailed: "Error generating file links timeline view", noTaggedFiles: "No files found with tag #{tag} or its subtags", noFileLinks: "No usable links or date information found in file {filename}", createViewFailed: "Cannot create timeline view: Please check sidebar space", noMetadataFiles: 'No files found matching metadata query "{query}"', generateMetadataFailed: "Failed to generate timeline from metadata" } }; // src/TimelineView.ts var import_obsidian2 = require("obsidian"); // src/Timeline.ts var import_obsidian = require("obsidian"); var Timeline = class { constructor(app, settings) { __publicField(this, "app"); __publicField(this, "settings"); this.app = app; this.settings = settings; } // 辅助函数:检查文件是否在timelines文件夹中 isInTimelinesFolder(file) { return file.path.startsWith("timelines/") || file.path === "timelines"; } async getFilePreview(file, tag) { const content = await this.app.vault.cachedRead(file); const normalizedTag = tag.replace(/^#/, ""); const tagLines = content.split("\n").filter((line) => { const tagRegex = new RegExp(`(^|s)#${normalizedTag}(?=s|$|[^w/])`); return tagRegex.test(line); }); if (tagLines.length > 0) { const firstTagLine = tagLines[0]; return firstTagLine.slice(0, 100) + (firstTagLine.length > 100 ? "..." : ""); } const previewContent = content.replace(/^---[\s\S]*?---/, "").trim(); return previewContent.slice(0, 50) + (previewContent.length > 50 ? "..." : ""); } async createTimelineItem(file, tag, metadataQuery) { var _a; const metadata = this.app.metadataCache.getFileCache(file); const dateValue = (_a = metadata == null ? void 0 : metadata.frontmatter) == null ? void 0 : _a[this.settings.dateAttribute]; if (dateValue) { const preview = tag ? await this.getFilePreview(file, tag) : await this.getFilePreview(file, ""); return { date: new Date(dateValue), title: file.basename, path: file.path, preview, isMilestone: this.checkMilestone(metadata == null ? void 0 : metadata.frontmatter) // 检查是否为里程碑 }; } return null; } checkMilestone(frontmatter) { if (!this.settings.milestoneAttribute || !frontmatter) { return false; } const attributeValue = frontmatter[this.settings.milestoneAttribute]; if (attributeValue === void 0 || attributeValue === null) { return false; } if (this.settings.milestoneValue === "") { return true; } return String(attributeValue).toLowerCase() === String(this.settings.milestoneValue).toLowerCase(); } sortItemsByDate(items) { return items.sort((a, b) => b.date.getTime() - a.date.getTime()); } extractLinkedFiles(content) { const linkedFiles = []; const linkRegex = /\[\[([^\]]+)\]\]/g; let match; while ((match = linkRegex.exec(content)) !== null) { const linkPath = match[1].split("|")[0]; const file = this.app.metadataCache.getFirstLinkpathDest(linkPath, ""); if (file && file instanceof import_obsidian.TFile) { linkedFiles.push(file); } } return linkedFiles; } async generateFromFileLinks(file) { const content = await this.app.vault.cachedRead(file); const linkedFiles = this.extractLinkedFiles(content); const items = []; for (const linkedFile of linkedFiles) { if (!this.isInTimelinesFolder(linkedFile)) { const item = await this.createTimelineItem(linkedFile); if (item) { items.push(item); } } } return this.sortItemsByDate(items); } async generateFromMetadata(metadataQuery) { const allFiles = this.app.vault.getMarkdownFiles(); const filteredFiles = allFiles.filter((file) => !this.isInTimelinesFolder(file)); const items = []; let queryKey; let queryValue = null; const firstColonIndex = metadataQuery.indexOf(":"); if (firstColonIndex > 0) { queryKey = metadataQuery.substring(0, firstColonIndex).trim(); queryValue = metadataQuery.substring(firstColonIndex + 1).trim(); if (queryValue === "") { queryValue = null; } } else { queryKey = metadataQuery.trim(); } for (const file of filteredFiles) { try { const cache = this.app.metadataCache.getFileCache(file); if (!cache || !cache.frontmatter) continue; const frontmatter = cache.frontmatter; let match = false; if (queryValue !== null) { const fmValue = frontmatter[queryKey]; if (fmValue !== void 0 && fmValue !== null) { if (Array.isArray(fmValue)) { const cleanedQueryValue = queryValue.startsWith("- ") ? queryValue.substring(2) : queryValue; match = fmValue.some((item) => { const itemStr = String(item).trim().toLowerCase(); const queryStr = cleanedQueryValue.toLowerCase(); return itemStr === queryStr || itemStr.includes(queryStr) || queryStr.includes(itemStr); }); } else { const fmValueStr = String(fmValue).trim().toLowerCase(); const queryValueStr = queryValue.toLowerCase(); match = fmValueStr === queryValueStr || fmValueStr.includes(queryValueStr) || queryValueStr.includes(fmValueStr); } } } else { match = Object.prototype.hasOwnProperty.call(frontmatter, queryKey); } if (match) { const item = await this.createTimelineItem(file, void 0, metadataQuery); if (item) { items.push(item); } } } catch (error) { console.error(`\u5904\u7406\u6587\u4EF6 ${file.path} \u65F6\u51FA\u9519:`, error); continue; } } return this.sortItemsByDate(items); } async generateFromFolder(folder) { if (folder.path === "timelines" || folder.path.startsWith("timelines/")) { return []; } const timelineItems = []; const processFolder = async (currentFolder) => { var _a; if (currentFolder.path === "timelines" || currentFolder.path.startsWith("timelines/")) { return; } for (const item of currentFolder.children) { if (item instanceof import_obsidian.TFile && item.extension === "md") { const metadata = this.app.metadataCache.getFileCache(item); const dateValue = (_a = metadata == null ? void 0 : metadata.frontmatter) == null ? void 0 : _a[this.settings.dateAttribute]; if (dateValue) { timelineItems.push({ date: new Date(dateValue), title: item.basename, path: item.path, preview: await this.getFilePreview(item, ""), isMilestone: this.checkMilestone(metadata == null ? void 0 : metadata.frontmatter) }); } } else if (item instanceof import_obsidian.TFolder) { await processFolder(item); } } }; await processFolder(folder); return timelineItems.sort((a, b) => b.date.getTime() - a.date.getTime()); } async generateFromTag(tag) { var _a; const allFiles = this.app.vault.getMarkdownFiles(); const filteredFiles = allFiles.filter((file) => !this.isInTimelinesFolder(file)); const items = []; const normalizedTag = tag.replace(/^#/, "").trim(); const isMatchingTag = (fileTag, searchTag) => { const cleanFileTag = fileTag.replace(/^#/, "").trim().toLowerCase(); const cleanSearchTag = searchTag.toLowerCase(); return cleanFileTag === cleanSearchTag || cleanFileTag.startsWith(cleanSearchTag + "/") || cleanSearchTag.includes(cleanFileTag); }; for (const file of filteredFiles) { try { const cache = this.app.metadataCache.getFileCache(file); if (!cache) continue; let hasMatchingTag = false; if (cache.tags && cache.tags.length > 0) { hasMatchingTag = cache.tags.some((tagObj) => { return isMatchingTag(tagObj.tag, normalizedTag); }); } if (!hasMatchingTag && ((_a = cache.frontmatter) == null ? void 0 : _a.tags)) { const frontmatterTags = cache.frontmatter.tags; if (Array.isArray(frontmatterTags)) { hasMatchingTag = frontmatterTags.some((frontmatterTag) => { if (typeof frontmatterTag !== "string") return false; return isMatchingTag(frontmatterTag, normalizedTag); }); } else if (typeof frontmatterTags === "string") { const normalizedTags = frontmatterTags.replace(/[,;]/g, " ").trim(); const tagList = normalizedTags.split(/\s+/); hasMatchingTag = tagList.some((tagItem) => { return isMatchingTag(tagItem, normalizedTag); }); } } if (hasMatchingTag) { const item = await this.createTimelineItem(file, normalizedTag); if (item) { items.push(item); } } } catch (error) { console.error(`\u5904\u7406\u6587\u4EF6 ${file.path} \u65F6\u51FA\u9519:`, error); continue; } } return this.sortItemsByDate(items); } async generateTimelineMarkdown(items, title, source) { let generatedFromValue = source.value; if (source.type === "metadata") { const parts = source.value.split(":"); const key = parts[0].trim(); const value = parts.slice(1).join(":").trim(); generatedFromValue = `${key}:${value}`; } let markdown = `--- generated_from: ${source.type}:${generatedFromValue} --- `; markdown += `# ${title} `; let currentYear = null; let currentMonth = null; for (const item of items) { const date = item.date; const year = date.getFullYear(); const month = date.getMonth(); if (currentYear !== year) { markdown += ` ## ${year} `; currentYear = year; currentMonth = null; } if (currentMonth !== month) { const monthName = this.settings.language === "zh-CN" ? date.toLocaleString("zh-CN", { month: "long" }) : date.toLocaleString("en-US", { month: "long" }); markdown += ` ### ${monthName} `; currentMonth = month; } const dateFormat = this.settings.language === "zh-CN" ? date.toLocaleDateString("zh-CN") : date.toLocaleDateString("en-US"); markdown += `#### ${dateFormat} - [[${item.title}]] `; } return markdown; } }; // src/TimelineView.ts var VIEW_TYPE_TIMELINE = "timeline-view"; var CLASS_TIMELINE_HEADER = "timeline-header"; var CLASS_TIMELINE_CONTAINER = "timeline-container"; var CLASS_TIMELINE_LINE = "timeline-line"; var CLASS_TIMELINE_ERA = "timeline-era"; var CLASS_TIMELINE_ERA_TITLE = "timeline-era-title"; var CLASS_TIMELINE_ITEM = "timeline-item"; var CLASS_TIMELINE_CARD = "timeline-card"; var CLASS_TIMELINE_DATE = "timeline-date"; var CLASS_TIMELINE_TITLE = "timeline-title"; var CLASS_TIMELINE_PREVIEW = "timeline-preview"; var TimelineView = class extends import_obsidian2.ItemView { constructor(leaf, settings, i18n) { super(leaf); __publicField(this, "timeline"); __publicField(this, "settings"); __publicField(this, "i18n"); __publicField(this, "items", []); __publicField(this, "currentTitle", ""); this.timeline = new Timeline(this.app, settings); this.settings = settings; this.i18n = i18n; } getViewType() { return VIEW_TYPE_TIMELINE; } getDisplayText() { return this.i18n.commands.openTimelineView; } async onOpen() { try { await this.render(); } catch (error) { new import_obsidian2.Notice(this.i18n.errors.renderFailed); } } async updateFromMetadata(metadataQuery) { try { this.currentTitle = `\u{1F50D} ${metadataQuery}`; this.items = await this.timeline.generateFromMetadata(metadataQuery); if (this.items.length === 0) { new import_obsidian2.Notice(this.i18n.errors.noMetadataFiles.replace("{query}", metadataQuery)); return; } await this.render(); } catch (error) { new import_obsidian2.Notice(this.i18n.errors.generateMetadataFailed); console.error("Error generating timeline from metadata:", error); } } renderTitle(container) { const titleContainer = container.createEl("div", { cls: CLASS_TIMELINE_HEADER }); titleContainer.createEl("h2", { text: this.currentTitle }); } groupItemsByYear() { const itemsByYear = /* @__PURE__ */ new Map(); this.items.forEach((item) => { var _a; const year = item.date.getFullYear(); if (!itemsByYear.has(year)) { itemsByYear.set(year, []); } (_a = itemsByYear.get(year)) == null ? void 0 : _a.push(item); }); return itemsByYear; } renderItem(container, item, index, itemsLength) { const itemClasses = [`${CLASS_TIMELINE_ITEM}${this.getItemClasses(index, itemsLength)}`]; if (item.isMilestone) { itemClasses.push("timeline-item-milestone"); } const itemEl = container.createEl("div", { cls: itemClasses.join(" "), attr: { style: `--timeline-line-color: ${this.settings.lineColor}` } }); const card = itemEl.createEl("div", { cls: CLASS_TIMELINE_CARD }); card.createEl("div", { cls: CLASS_TIMELINE_DATE, text: item.date.toLocaleDateString(this.settings.language === "zh-CN" ? "zh-CN" : "en-US") }); const titleEl = card.createEl("div", { cls: CLASS_TIMELINE_TITLE, attr: { style: `color: ${item.isMilestone ? this.settings.milestoneCardTextColor : this.settings.cardTextColor} !important` } }); titleEl.textContent = item.title; titleEl.dataset.colorSetting = item.isMilestone ? "milestoneCardTextColor" : "cardTextColor"; if (item.preview) { const previewEl = card.createEl("div", { cls: CLASS_TIMELINE_PREVIEW, attr: { style: `color: ${item.isMilestone ? this.settings.milestoneCardTextColor : this.settings.cardTextColor} !important` } }); previewEl.textContent = item.preview; previewEl.dataset.colorSetting = item.isMilestone ? "milestoneCardTextColor" : "cardTextColor"; } titleEl.addEventListener("click", async () => { const file = this.app.vault.getAbstractFileByPath(item.path); if (file instanceof import_obsidian2.TFile) { await this.app.workspace.getLeaf().openFile(file); } }); } getItemClasses(index, itemsLength) { return (index === 0 ? " first-item" : "") + (index === itemsLength - 1 ? " last-item" : ""); } renderEra(container, year, items) { const era = container.createEl("div", { cls: CLASS_TIMELINE_ERA }); era.createEl("div", { cls: CLASS_TIMELINE_ERA_TITLE, text: `${year}` }); items.forEach((item, index) => this.renderItem(era, item, index, items.length)); } async render() { const container = this.containerEl.children[1]; container.empty(); if (this.currentTitle) { this.renderTitle(container); } const timelineContainer = container.createEl("div", { cls: CLASS_TIMELINE_CONTAINER }); timelineContainer.createEl("div", { cls: CLASS_TIMELINE_LINE }); const itemsByYear = this.groupItemsByYear(); Array.from(itemsByYear.entries()).sort(([yearA], [yearB]) => yearB - yearA).forEach(([year, items]) => this.renderEra(timelineContainer, year, items)); } async updateFromFolder(folderPath) { const folder = this.app.vault.getAbstractFileByPath(folderPath); if (folder) { this.currentTitle = `\u{1F4C2} ${folder.name}`; this.items = await this.timeline.generateFromFolder(folder); await this.render(); } } async updateFromTag(tag) { try { this.currentTitle = `\u{1F3F7}\uFE0F ${tag}`; this.items = await this.timeline.generateFromTag(tag); if (this.items.length === 0) { new import_obsidian2.Notice(this.i18n.errors.noTaggedFiles.replace("{tag}", tag)); return; } await this.render(); } catch (error) { new import_obsidian2.Notice("\u751F\u6210\u65F6\u95F4\u8F74\u5931\u8D25"); throw error; } } async updateFromFile(filePath) { try { const file = this.app.vault.getAbstractFileByPath(filePath); if (file && file instanceof import_obsidian2.TFile) { this.currentTitle = `\u{1F4C4} ${file.basename}`; this.items = await this.timeline.generateFromFileLinks(file); if (this.items.length === 0) { new import_obsidian2.Notice(this.i18n.errors.noFileLinks.replace("{filename}", file.basename)); return; } await this.render(); } } catch (error) { new import_obsidian2.Notice(this.i18n.errors.generateFileFailed); console.error(error); } } getIcon() { return "history"; } }; // src/FolderSuggest.ts var import_obsidian3 = require("obsidian"); var FolderSuggestModal = class extends import_obsidian3.FuzzySuggestModal { constructor(app, settings) { super(app); this.settings = settings; __publicField(this, "resolve"); this.setPlaceholder(this.settings.language === "zh-CN" ? "\u9009\u62E9\u4E00\u4E2A\u6587\u4EF6\u5939" : "Select a folder"); } getItems() { const folders = []; const shouldFilterFolder = (folderPath) => { return folderPath === "timelines" || folderPath.startsWith("timelines/"); }; const pushFolder = (folder) => { if (!shouldFilterFolder(folder.path)) { folders.push(folder); folder.children.filter((child) => child instanceof import_obsidian3.TFolder).forEach(pushFolder); } }; const rootFolder = this.app.vault.getRoot(); pushFolder(rootFolder); return folders; } getItemText(folder) { return folder.path; } onChooseItem(folder) { this.resolve(folder.path); this.close(); } async openAndGetValue() { return new Promise((resolve) => { this.resolve = resolve; this.open(); }).then((value) => { if (value === void 0) { return null; } return value; }); } }; // src/TagSuggest.ts var import_obsidian4 = require("obsidian"); var TagSuggestModal = class extends import_obsidian4.FuzzySuggestModal { constructor(app, settings) { super(app); this.settings = settings; __publicField(this, "resolve"); this.setPlaceholder(this.settings.language === "zh-CN" ? "\u9009\u62E9\u4E00\u4E2A\u6807\u7B7E" : "Select a tag"); } getItems() { const tags = /* @__PURE__ */ new Set(); const files = this.app.vault.getMarkdownFiles(); files.forEach((file) => { var _a, _b; const cache = this.app.metadataCache.getFileCache(file); (_a = cache == null ? void 0 : cache.tags) == null ? void 0 : _a.forEach((tag) => { tags.add(tag.tag.replace("#", "")); }); const frontmatterTags = (_b = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _b.tags; if (Array.isArray(frontmatterTags)) { frontmatterTags.forEach((tag) => { tags.add(tag.replace("#", "")); }); } else if (typeof frontmatterTags === "string") { const normalizedTags = frontmatterTags.replace(/[,;]/g, " ").trim(); normalizedTags.split(/\s+/).forEach((tag) => { if (tag) { tags.add(tag.trim().replace("#", "")); } }); } }); const tagArray = Array.from(tags); console.log("\u53EF\u7528\u7684\u6807\u7B7E:", tagArray); return tagArray; } getItemText(tag) { return tag; } onChooseItem(tag) { console.log("\u9009\u62E9\u7684\u6807\u7B7E:", tag); this.resolve(tag); this.close(); } async openAndGetValue() { return new Promise((resolve) => { this.resolve = resolve; this.open(); }); } }; // src/FileSuggest.ts var import_obsidian5 = require("obsidian"); var FileSuggestModal = class extends import_obsidian5.FuzzySuggestModal { constructor(app, settings) { super(app); this.settings = settings; __publicField(this, "resolve"); this.setPlaceholder(this.settings.language === "zh-CN" ? "\u9009\u62E9\u4E00\u4E2AMarkdown\u6587\u4EF6" : "Select a Markdown file"); } async openAndGetValue() { return new Promise((resolve) => { this.resolve = resolve; this.open(); }); } getItems() { return this.app.vault.getMarkdownFiles().filter( (file) => !file.path.startsWith("timelines/") && file.path !== "timelines" ); } getItemText(file) { return file.path; } onChooseItem(file) { this.resolve(file); this.close(); } }; // src/TimelineSettings.ts function getCssVariable(name) { return `var(${name})`; } var DEFAULT_SETTINGS = { lineWidth: 2, lineColor: getCssVariable("--interactive-accent"), itemSpacing: 30, cardBackground: getCssVariable("--background-primary-alt"), cardTextColor: getCssVariable("--text-normal"), cardBorderColor: getCssVariable("--background-modifier-border"), milestoneCardBackground: "#ffffcc", milestoneCardTextColor: getCssVariable("--text-normal"), milestoneCardBorderColor: "#f0e68c", animationDuration: 200, dateAttribute: "created", // 默认使用 frontmatter 中的 date 属性作为时间轴排序依据 fileNamePrefix: "", fileNameSuffix: "", defaultPosition: "right", // 默认在右侧边栏 language: "zh-CN", // 默认使用中文 milestoneAttribute: "", // 默认不使用里程碑属性 milestoneValue: "" // 默认值为空 }; // src/main.ts var import_obsidian7 = require("obsidian"); var TimelinePlugin = class extends import_obsidian6.Plugin { constructor() { super(...arguments); __publicField(this, "settings"); __publicField(this, "i18n"); } async onload() { await this.loadSettings(); this.i18n = this.settings.language === "zh-CN" ? zhCN : enUS; this.addSettingTab(new TimelineSettingTab(this.app, this)); console.log("\u52A0\u8F7D Timeline \u63D2\u4EF6"); try { this.registerView( VIEW_TYPE_TIMELINE, (leaf) => new TimelineView(leaf, this.settings, this.i18n) ); this.registerEvent( this.app.workspace.on("file-menu", (menu, abstractFile) => { var _a; if (abstractFile instanceof import_obsidian6.TFile && abstractFile.path.startsWith("timelines/") && abstractFile.extension === "md") { const cache = this.app.metadataCache.getFileCache(abstractFile); const generatedFrom = (_a = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _a.generated_from; if (generatedFrom) { const [type, ...valueParts] = generatedFrom.split(":"); const value = valueParts.join(":"); menu.addItem((item) => { item.setTitle(this.i18n.commands.openTimelineView).setIcon("clock").onClick(async () => { await this.activateView(this.settings.defaultPosition); const view = this.getTimelineView(); if (view) { if (type === "folder") { await view.updateFromFolder(value); } else if (type === "tag") { await view.updateFromTag(value); } else if (type === "file") { await view.updateFromFile(value); } else if (type === "metadata") { await view.updateFromMetadata(value); } } }); }); } } }) ); this.addCommand({ id: "generate-timeline-view-from-folder", name: this.i18n.commands.generateFromFolder, callback: async () => { try { const folderPath = await this.selectFolder(); if (folderPath) { await this.activateView(this.settings.defaultPosition); const view = this.getTimelineView(); if (view) { await view.updateFromFolder(folderPath); } } } catch (error) { console.error("\u751F\u6210\u6587\u4EF6\u5939\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519:", error); } } }); this.addCommand({ id: "generate-timeline-file-from-folder", name: this.i18n.commands.generateFileFromFolder, callback: async () => { try { const folderPath = await this.selectFolder(); if (folderPath) { const folder = this.app.vault.getAbstractFileByPath(folderPath); if (!(folder instanceof import_obsidian7.TFolder)) { throw new Error(`Invalid folder path: ${folderPath}`); } const timeline = new Timeline(this.app, this.settings); const items = await timeline.generateFromFolder(folder); const content = await timeline.generateTimelineMarkdown(items, `Timeline - ${folderPath}`, { type: "folder", value: folderPath }); const { folderPath: targetFolder, fileName } = await this.createNestedFolders(folderPath); const finalFileName = this.generateFileName(fileName || folderPath.split("/").pop() || ""); const filePath = `${targetFolder}/${finalFileName}.md`; const existingFile = this.app.vault.getAbstractFileByPath(filePath); if (existingFile) { await this.app.vault.delete(existingFile); } const file = await this.app.vault.create(filePath, content); await this.app.workspace.getLeaf().openFile(file); } } catch (error) { console.error("\u751F\u6210\u6587\u4EF6\u5939\u65F6\u95F4\u8F74\u6587\u4EF6\u65F6\u51FA\u9519:", error); } } }); this.addCommand({ id: "generate-timeline-view-from-tag", name: this.i18n.commands.generateFromTag, callback: async () => { try { const tag = await this.selectTag(); if (tag) { await this.activateView(this.settings.defaultPosition); const view = this.getTimelineView(); if (view) { await view.updateFromTag(tag); } } } catch (error) { console.error("\u751F\u6210\u6807\u7B7E\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519:", error); } } }); this.addCommand({ id: "generate-timeline-file-from-tag", name: this.i18n.commands.generateFileFromTag, callback: async () => { try { const tag = await this.selectTag(); if (tag) { await this.generateTimelineFileFromTag(tag); } } catch (error) { console.error("\u751F\u6210\u6807\u7B7E\u65F6\u95F4\u8F74\u6587\u4EF6\u65F6\u51FA\u9519:", error); } } }); this.addCommand({ id: "generate-timeline-view-from-file-links", name: this.i18n.commands.generateFromFileLinks, callback: async () => { try { const file = this.app.workspace.getActiveFile(); if (!file || !(file instanceof import_obsidian6.TFile) || file.extension !== "md") { new import_obsidian6.Notice(this.i18n.errors.generateFileFailed); return; } const cache = this.app.metadataCache.getFileCache(file); if (!cache || !cache.links || cache.links.length === 0) { new import_obsidian6.Notice(this.i18n.errors.noFileLinks.replace("{filename}", file.basename)); return; } await this.activateView(this.settings.defaultPosition); const view = this.getTimelineView(); if (view) { const timeline = new Timeline(this.app, this.settings); const items = await timeline.generateFromFileLinks(file); view.items = items; view.currentTitle = `\u{1F517} ${file.basename} `; await view.render(); } } catch (error) { console.error("\u4ECE\u6587\u4EF6\u94FE\u63A5\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519:", error); new import_obsidian6.Notice(this.i18n.errors.generateFileFailed); } } }); this.addCommand({ id: "generate-timeline-file-from-file-links", name: this.i18n.commands.generateFileFromFileLinks, callback: async () => { try { const file = this.app.workspace.getActiveFile(); if (!file || !(file instanceof import_obsidian6.TFile) || file.extension !== "md") { new import_obsidian6.Notice(this.i18n.errors.generateFileFailed); return; } const cache = this.app.metadataCache.getFileCache(file); if (!cache || !cache.links || cache.links.length === 0) { new import_obsidian6.Notice(this.i18n.errors.noFileLinks.replace("{filename}", file.basename)); return; } const timeline = new Timeline(this.app, this.settings); const items = await timeline.generateFromFileLinks(file); const content = await timeline.generateTimelineMarkdown( items, `Timeline - Links in ${file.basename}`, { type: "file", value: file.path } ); const { folderPath } = await this.createNestedFolders("linked-files"); const finalFileName = this.generateFileName(file.basename); const filePath = `${folderPath}/${finalFileName}.md`; const existingFile = this.app.vault.getAbstractFileByPath(filePath); if (existingFile) { await this.app.vault.delete(existingFile); } const newFile = await this.app.vault.create(filePath, content); await this.app.workspace.getLeaf().openFile(newFile); } catch (error) { console.error("\u4ECE\u6587\u4EF6\u94FE\u63A5\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6\u65F6\u51FA\u9519:", error); new import_obsidian6.Notice(this.i18n.errors.generateFileFailed); } } }); this.addCommand({ id: "generate-timeline-view-from-metadata", name: this.i18n.commands.generateFromMetadata, callback: async () => { try { const metadataQuery = await this.selectMetadataString(); if (metadataQuery) { await this.activateView(this.settings.defaultPosition); const view = this.getTimelineView(); if (view) { await view.updateFromMetadata(metadataQuery); } } } catch (error) { console.error("\u4ECE\u5143\u6570\u636E\u751F\u6210\u65F6\u95F4\u8F74\u89C6\u56FE\u65F6\u51FA\u9519:", error); new import_obsidian6.Notice(this.i18n.errors.generateMetadataFailed); } } }); this.addCommand({ id: "generate-timeline-file-from-metadata", name: this.i18n.commands.generateFileFromMetadata, callback: async () => { try { const metadataQuery = await this.selectMetadataString(); if (metadataQuery) { const timeline = new Timeline(this.app, this.settings); const items = await timeline.generateFromMetadata(metadataQuery); const content = await timeline.generateTimelineMarkdown( items, `Timeline - Metadata: ${metadataQuery}`, { type: "metadata", value: metadataQuery } ); const { folderPath } = await this.createNestedFolders("metadata-search"); const safeBaseName = metadataQuery.substring(0, 30).replace(/[^a-zA-Z0-9_\-]+/g, "_") || "metadata_query"; const finalFileName = this.generateFileName(safeBaseName); const filePath = `${folderPath}/${finalFileName}.md`; const existingFile = this.app.vault.getAbstractFileByPath(filePath); if (existingFile) { await this.app.vault.delete(existingFile); } const newFile = await this.app.vault.create(filePath, content); await this.app.workspace.getLeaf().openFile(newFile); } } catch (error) { console.error("\u4ECE\u5143\u6570\u636E\u751F\u6210\u65F6\u95F4\u8F74\u6587\u4EF6\u65F6\u51FA\u9519:", error); new import_obsidian6.Notice(this.i18n.errors.generateMetadataFailed); } } }); this.registerEvent( this.app.workspace.on("file-open", async (file) => { var _a; if (file instanceof import_obsidian6.TFile && file.path.startsWith("timelines/") && file.extension === "md") { const cache = this.app.metadataCache.getFileCache(file); const generatedFrom = (_a = cache == null ? void 0 : cache.frontmatter) == null ? void 0 : _a.generated_from; if (generatedFrom) { const [type, ...valueParts] = generatedFrom.split(":"); const value = valueParts.join(":"); const timeline = new Timeline(this.app, this.settings); let items = []; if (type === "folder") { const folder = this.app.vault.getAbstractFileByPath(value); if (folder instanceof import_obsidian7.TFolder) { items = await timeline.generateFromFolder(folder); } } else if (type === "tag") { items = await timeline.generateFromTag(value); } else if (type === "file") { const targetFile = this.app.vault.getAbstractFileByPath(value); if (targetFile instanceof import_obsidian6.TFile) { items = await timeline.generateFromFileLinks(targetFile); } } else if (type === "metadata") { items = await timeline.generateFromMetadata(value); } const content = await timeline.generateTimelineMarkdown(items, `Timeline - ${value}`, { type, value }); await this.app.vault.modify(file, content); } } }) ); } catch (error) { console.error("\u63D2\u4EF6\u52A0\u8F7D\u65F6\u51FA\u9519:", error); } } async selectFolder() { const modal = new FolderSuggestModal(this.app, this.settings); return await modal.openAndGetValue(); } async selectFile() { const modal = new FileSuggestModal(this.app, this.settings); return await modal.openAndGetValue(); } async selectTag() { const modal = new TagSuggestModal(this.app, this.settings); return await modal.openAndGetValue(); } async selectMetadataString() { const modal = new MetadataInputModal(this.app, this); return await modal.openAndGetValue(); } async activateView(position = this.settings.defaultPosition) { const { workspace } = this.app; const leaves = workspace.getLeavesOfType(VIEW_TYPE_TIMELINE); if (leaves.length > 0) { workspace.revealLeaf(leaves[0]); return leaves[0]; } const newLeaf = position === "left" ? workspace.getLeftLeaf(false) : workspace.getRightLeaf(false); if (!newLeaf) { new import_obsidian6.Notice("\u65E0\u6CD5\u521B\u5EFA\u65F6\u95F4\u8F74\u89C6\u56FE\uFF1A\u8BF7\u68C0\u67E5\u4FA7\u8FB9\u680F\u7A7A\u95F4"); return null; } await newLeaf.setViewState({ type: VIEW_TYPE_TIMELINE }); workspace.revealLeaf(newLeaf); return newLeaf; } getTimelineView() { const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_TIMELINE); if (leaves.length === 0) { return null; } return leaves[0].view; } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); this.updateStyles(); } async saveSettings() { await this.saveData(this.settings); this.updateStyles(); } updateStyles() { var _a; const style = document.createElement("style"); style.id = "timeline-custom-styles"; style.textContent = ` .timeline-line { width: ${this.settings.lineWidth}px !important; background: ${this.settings.lineColor} !important; } .timeline-item::after { background: var(--timeline-line-color, ${this.settings.lineColor}) !important; } .timeline-item { margin: ${this.settings.itemSpacing}px 0 !important; } .timeline-card { background: ${this.settings.cardBackground} !important; color: ${this.settings.cardTextColor} !important; border: 1px solid ${this.settings.cardBorderColor} !important; transition: transform ${this.settings.animationDuration}ms !important; } .timeline-item-milestone .timeline-card { background: ${this.settings.milestoneCardBackground} !important; color: ${this.settings.milestoneCardTextColor} !important; border: 1px solid ${this.settings.milestoneCardBorderColor} !important; } [data-color-setting="cardTextColor"] { color: ${this.settings.cardTextColor} !important; } [data-color-setting="milestoneCardTextColor"] { color: ${this.settings.milestoneCardTextColor} !important; } .timeline-date { color: ${this.settings.cardTextColor} !important; } .timeline-item-milestone .timeline-date { color: ${this.settings.milestoneCardTextColor} !important; } .timeline-era-title { color: var(--timeline-line-color, ${this.settings.lineColor}) !important; } `; (_a = document.getElementById("timeline-custom-styles")) == null ? void 0 : _a.remove(); document.head.appendChild(style); } async createNestedFolders(tagPath) { const rootPath = "timelines"; if (!this.app.vault.getAbstractFileByPath(rootPath)) { try { await this.app.vault.createFolder(rootPath); } catch (error) { new import_obsidian6.Notice(`\u521B\u5EFA\u6839\u76EE\u5F55\u5931\u8D25: ${rootPath}`); throw error; } } const parts = tagPath.split("/"); const fileName = parts.pop(); let currentPath = rootPath; for (const part of parts) { currentPath = (0, import_obsidian6.normalizePath)(`${currentPath}/${part}`); const folder = this.app.vault.getAbstractFileByPath(currentPath); if (!folder) { try { await this.app.vault.createFolder(currentPath); } catch (error) { new import_obsidian6.Notice(`\u521B\u5EFA\u6587\u4EF6\u5939\u5931\u8D25: ${currentPath}`); throw error; } } } return { folderPath: currentPath, fileName }; } generateFileName(baseName) { const prefix = this.settings.fileNamePrefix || ""; const suffix = this.settings.fileNameSuffix || ""; return `${prefix}${baseName}${suffix}`; } async generateTimelineFileFromTag(tag) { try { const tagPath = tag.replace("#", ""); const { folderPath, fileName } = await this.createNestedFolders(tagPath); const finalFileName = this.generateFileName(fileName || ""); const filePath = `${folderPath}/${finalFileName}.md`; const existingFile = this.app.vault.getAbstractFileByPath(filePath); if (existingFile) { await this.app.vault.delete(existingFile); } const timeline = new Timeline(this.app, this.settings); const items = await timeline.generateFromTag(tag); const content = await timeline.generateTimelineMarkdown(items, `Timeline - ${tag}`, { type: "tag", value: tag }); const file = await this.app.vault.create(filePath, content); await this.app.workspace.getLeaf().openFile(file); } catch (error) { console.error("\u751F\u6210\u6807\u7B7E\u65F6\u95F4\u8F74\u6587\u4EF6\u65F6\u51FA\u9519:", error); throw error; } } }; var MetadataInputModal = class extends import_obsidian6.Modal { constructor(app, plugin) { super(app); __publicField(this, "plugin"); // Add plugin reference __publicField(this, "value", ""); __publicField(this, "resolvePromise"); __publicField(this, "inputEl"); this.plugin = plugin; } async openAndGetValue() { return new Promise((resolve) => { this.resolvePromise = resolve; this.open(); }); } onOpen() { const { contentEl } = this; contentEl.empty(); contentEl.addClass("metadata-input-modal"); contentEl.createEl("h2", { text: this.plugin.i18n.modal.metadataInputTitle }); new import_obsidian6.Setting(contentEl).setName(this.plugin.i18n.modal.metadataQueryName).setDesc(this.plugin.i18n.modal.metadataQueryDesc).addText((text) => { this.inputEl = text; text.setPlaceholder(this.plugin.i18n.modal.metadataInputPlaceholder).onChange((value) => this.value = value.trim()); text.inputEl.style.width = "100%"; text.inputEl.addEventListener("keydown", (evt) => { if (evt.key === "Enter") { evt.preventDefault(); this.submit(); } }); }); new import_obsidian6.Setting(contentEl).addButton((button) => button.setButtonText(this.plugin.i18n.modal.submitButton).setCta().onClick(() => this.submit())).addButton((button) => button.setButtonText(this.plugin.i18n.modal.cancelButton).onClick(() => this.closeAndResolve(null))); setTimeout(() => { if (this.inputEl && this.inputEl.inputEl) { this.inputEl.inputEl.focus(); } }, 50); } submit() { if (this.value) { this.closeAndResolve(this.value); } else { new import_obsidian6.Notice(this.plugin.i18n.modal.emptyInputNotice); } } closeAndResolve(value) { if (this.resolvePromise) { this.resolvePromise(value); } this.close(); } onClose() { const { contentEl } = this; contentEl.empty(); } }; var TimelineSettingTab = class extends import_obsidian6.PluginSettingTab { constructor(app, plugin) { super(app, plugin); __publicField(this, "plugin"); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.resetSettings).setDesc(this.plugin.i18n.settings.resetSettingsDesc).addButton((button) => button.setButtonText(this.plugin.i18n.settings.resetSettingsButton).onClick(async () => { this.plugin.settings = Object.assign({}, DEFAULT_SETTINGS); await this.plugin.saveSettings(); this.display(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.language).setDesc(this.plugin.i18n.settings.languageDesc).addDropdown((dropdown) => dropdown.addOption("zh-CN", "\u4E2D\u6587").addOption("en-US", "English").setValue(this.plugin.settings.language).onChange(async (value) => { this.plugin.settings.language = value; this.plugin.i18n = value === "zh-CN" ? zhCN : enUS; await this.plugin.saveSettings(); this.display(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.milestoneAttribute).setDesc(this.plugin.i18n.settings.milestoneAttributeDesc).addText((text) => text.setPlaceholder("milestone").setValue(this.plugin.settings.milestoneAttribute).onChange(async (value) => { this.plugin.settings.milestoneAttribute = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.milestoneValue).setDesc(this.plugin.i18n.settings.milestoneValueDesc).addText((text) => text.setPlaceholder("true or 1 (leave empty to match any value)").setValue(this.plugin.settings.milestoneValue).onChange(async (value) => { this.plugin.settings.milestoneValue = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.lineWidth).setDesc(this.plugin.i18n.settings.lineWidthDesc).addSlider((slider) => slider.setLimits(1, 10, 1).setValue(this.plugin.settings.lineWidth).onChange(async (value) => { this.plugin.settings.lineWidth = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.lineColor).setDesc(this.plugin.i18n.settings.lineColorDesc).addColorPicker((color) => color.setValue(this.plugin.settings.lineColor).onChange(async (value) => { this.plugin.settings.lineColor = value; await this.plugin.saveSettings(); })).addText((text) => text.setPlaceholder(this.plugin.i18n.settings.colorPickerPlaceholder).setValue("").onChange(async (value) => { if (value) { this.plugin.settings.lineColor = value; await this.plugin.saveSettings(); } })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.itemSpacing).setDesc(this.plugin.i18n.settings.itemSpacingDesc).addSlider((slider) => slider.setLimits(10, 100, 5).setValue(this.plugin.settings.itemSpacing).onChange(async (value) => { this.plugin.settings.itemSpacing = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.cardBackground).setDesc(this.plugin.i18n.settings.cardBackgroundDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.cardBackground).onChange(async (value) => { this.plugin.settings.cardBackground = value; await this.plugin.saveSettings(); }) ).setTooltip(this.plugin.i18n.settings.colorPickerPlaceholder); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.cardTextColor).setDesc(this.plugin.i18n.settings.cardTextColorDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.cardTextColor).onChange(async (value) => { this.plugin.settings.cardTextColor = value; await this.plugin.saveSettings(); }) ); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.cardBorderColor).setDesc(this.plugin.i18n.settings.cardBorderColorDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.cardBorderColor).onChange(async (value) => { this.plugin.settings.cardBorderColor = value; await this.plugin.saveSettings(); }) ); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.milestoneCardBackground).setDesc(this.plugin.i18n.settings.milestoneCardBackgroundDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.milestoneCardBackground).onChange(async (value) => { this.plugin.settings.milestoneCardBackground = value; await this.plugin.saveSettings(); }) ); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.milestoneCardTextColor).setDesc(this.plugin.i18n.settings.milestoneCardTextColorDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.milestoneCardTextColor).onChange(async (value) => { this.plugin.settings.milestoneCardTextColor = value; await this.plugin.saveSettings(); }) ); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.milestoneCardBorderColor).setDesc(this.plugin.i18n.settings.milestoneCardBorderColorDesc).addColorPicker( (color) => color.setValue(this.plugin.settings.milestoneCardBorderColor).onChange(async (value) => { this.plugin.settings.milestoneCardBorderColor = value; await this.plugin.saveSettings(); }) ); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.animationDuration).setDesc(this.plugin.i18n.settings.animationDurationDesc).addSlider((slider) => slider.setLimits(0, 1e3, 50).setValue(this.plugin.settings.animationDuration).onChange(async (value) => { this.plugin.settings.animationDuration = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.dateAttribute).setDesc(this.plugin.i18n.settings.dateAttributeDesc).addText((text) => text.setPlaceholder("created").setValue(this.plugin.settings.dateAttribute).onChange(async (value) => { this.plugin.settings.dateAttribute = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.fileNamePrefix).setDesc(this.plugin.i18n.settings.fileNamePrefixDesc).addText((text) => text.setPlaceholder("").setValue(this.plugin.settings.fileNamePrefix).onChange(async (value) => { this.plugin.settings.fileNamePrefix = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.fileNameSuffix).setDesc(this.plugin.i18n.settings.fileNameSuffixDesc).addText((text) => text.setPlaceholder("").setValue(this.plugin.settings.fileNameSuffix).onChange(async (value) => { this.plugin.settings.fileNameSuffix = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName(this.plugin.i18n.settings.defaultPosition).setDesc(this.plugin.i18n.settings.defaultPositionDesc).addDropdown( (dropdown) => dropdown.addOption("left", this.plugin.i18n.settings.leftSidebar).addOption("right", this.plugin.i18n.settings.rightSidebar).setValue(this.plugin.settings.defaultPosition).onChange(async (value) => { this.plugin.settings.defaultPosition = value; await this.plugin.saveSettings(); }) ); } }; /* nosourcemap */