diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 67d2e2d..febaa19 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -46,7 +46,7 @@ esbuild.build({ copy({ assets: [{ from: ["./manifest.json", "./main.js", "./styles.css"], - to: ["./test-vault/.obsidian/plugins/obsidian-simple-time-tracker/."] + to: ["./test-vault/.obsidian/plugins/simple-time-tracker/."] }] }), ], diff --git a/manifest.json b/manifest.json index 514dc0c..5c426fd 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { - "id": "obsidian-simple-time-tracker", + "id": "simple-time-tracker", "name": "Super Simple Time Tracker", "version": "0.1.1", "minAppVersion": "0.15.0", diff --git a/package-lock.json b/package-lock.json index a64259e..f3c6bda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "obsidian-simple-time-tracker", + "name": "simple-time-tracker", "version": "0.1.1", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index 4acb5a0..2bf7d73 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "obsidian-simple-time-tracker", + "name": "simple-time-tracker", "version": "0.1.1", "description": "Multi-purpose time trackers for your notes!", "main": "main.js", diff --git a/src/main.ts b/src/main.ts index 2918211..6e0dd94 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,7 +19,7 @@ export default class SimpleTimeTrackerPlugin extends Plugin { }); this.addCommand({ - id: `insert-simple-time-tracker`, + id: `insert`, name: `Insert Time Tracker`, editorCallback: (e, _) => { e.replaceSelection("```simple-time-tracker\n```\n"); diff --git a/test-vault/.obsidian/community-plugins.json b/test-vault/.obsidian/community-plugins.json index 257504c..655cfd3 100644 --- a/test-vault/.obsidian/community-plugins.json +++ b/test-vault/.obsidian/community-plugins.json @@ -1,3 +1,3 @@ [ - "obsidian-simple-time-tracker" + "simple-time-tracker" ] \ No newline at end of file diff --git a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/main.js b/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/main.js deleted file mode 100644 index 819f4d8..0000000 --- a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/main.js +++ /dev/null @@ -1,274 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ESBUILD -if you want to view the source, please visit the github repository of this plugin -*/ -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); -var __export = (target, all) => { - __markAsModule(target); - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __reExport = (target, module2, desc) => { - if (module2 && typeof module2 === "object" || typeof module2 === "function") { - for (let key of __getOwnPropNames(module2)) - if (!__hasOwnProp.call(target, key) && key !== "default") - __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); - } - return target; -}; -var __toModule = (module2) => { - return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); -}; -var __async = (__this, __arguments, generator) => { - return new Promise((resolve, reject) => { - var fulfilled = (value) => { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - }; - var rejected = (value) => { - try { - step(generator.throw(value)); - } catch (e) { - reject(e); - } - }; - var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); - step((generator = generator.apply(__this, __arguments)).next()); - }); -}; - -// src/main.ts -__export(exports, { - default: () => SimpleTimeTrackerPlugin -}); -var import_obsidian3 = __toModule(require("obsidian")); - -// src/settings.ts -var defaultSettings = { - timestampFormat: "YY-MM-DD hh:mm:ss", - csvDelimiter: "," -}; - -// src/settings-tab.ts -var import_obsidian = __toModule(require("obsidian")); -var SimpleTimeTrackerSettingsTab = class extends import_obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - this.containerEl.empty(); - this.containerEl.createEl("h2", { text: "Super Simple Time Tracker Settings" }); - new import_obsidian.Setting(this.containerEl).setName("Timestamp Display Format").setDesc(createFragment((f) => { - f.createSpan({ text: "The way that timestamps in time tracker tables should be displayed. Uses " }); - f.createEl("a", { text: "moment.js", href: "https://momentjs.com/docs/#/parsing/string-format/" }); - f.createSpan({ text: " syntax." }); - })).addText((t) => { - t.setValue(String(this.plugin.settings.timestampFormat)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.timestampFormat = v.length ? v : defaultSettings.timestampFormat; - yield this.plugin.saveSettings(); - })); - }); - new import_obsidian.Setting(this.containerEl).setName("CSV Delimiter").setDesc("The delimiter character that should be used when copying a tracker table as CSV. For example, some languages use a semicolon instead of a comma.").addText((t) => { - t.setValue(String(this.plugin.settings.csvDelimiter)); - t.onChange((v) => __async(this, null, function* () { - this.plugin.settings.csvDelimiter = v.length ? v : defaultSettings.csvDelimiter; - yield this.plugin.saveSettings(); - })); - }); - this.containerEl.createEl("hr"); - this.containerEl.createEl("p", { text: "If you like this plugin and want to support its development, you can do so through my website by clicking this fancy image!" }); - this.containerEl.createEl("a", { href: "https://ellpeck.de/support" }).createEl("img", { attr: { src: "https://ellpeck.de/res/generalsupport.png" }, cls: "simple-time-tracker-support" }); - } -}; - -// src/tracker.ts -var import_obsidian2 = __toModule(require("obsidian")); -function startEntry(tracker, name) { - if (!name) - name = `Segment ${tracker.entries.length + 1}`; - let entry = { name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null }; - tracker.entries.push(entry); -} -function endEntry(tracker) { - let last = tracker.entries.last(); - last.endTime = (0, import_obsidian2.moment)().unix(); -} -function isRunning(tracker) { - let last = tracker.entries.last(); - return last != null && !last.endTime; -} -function saveTracker(tracker, app, section) { - return __async(this, null, function* () { - let file = app.workspace.getActiveFile(); - let content = yield app.vault.cachedRead(file); - let lines = content.split("\n"); - let prev = lines.filter((_, i) => i <= section.lineStart).join("\n"); - let next = lines.filter((_, i) => i >= section.lineEnd).join("\n"); - content = `${prev} -${JSON.stringify(tracker)} -${next}`; - yield app.vault.modify(file, content); - }); -} -function loadTracker(json) { - if (json) { - try { - return JSON.parse(json); - } catch (e) { - console.log(`Failed to parse Tracker from ${json}`); - } - } - return { entries: [] }; -} -function displayTracker(tracker, element, getSectionInfo, settings) { - let running = isRunning(tracker); - let btn = new import_obsidian2.ButtonComponent(element).setButtonText(running ? "End" : "Start").onClick(() => __async(this, null, function* () { - if (running) { - endEntry(tracker); - } else { - startEntry(tracker, name.getValue()); - } - yield saveTracker(tracker, this.app, getSectionInfo()); - })); - btn.buttonEl.addClass("simple-time-tracker-btn"); - let name = new import_obsidian2.TextComponent(element).setPlaceholder("Segment name").setDisabled(running); - name.inputEl.addClass("simple-time-tracker-txt"); - let timer = element.createDiv({ cls: "simple-time-tracker-timers" }); - let currentDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let current = currentDiv.createEl("span", { cls: "simple-time-tracker-timer-time" }); - currentDiv.createEl("span", { text: "Current" }); - let totalDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); - let total = totalDiv.createEl("span", { cls: "simple-time-tracker-timer-time", text: "0s" }); - totalDiv.createEl("span", { text: "Total" }); - if (tracker.entries.length > 0) { - let table = element.createEl("table", { cls: "simple-time-tracker-table" }); - table.createEl("tr").append(createEl("th", { text: "Segment" }), createEl("th", { text: "Start time" }), createEl("th", { text: "End time" }), createEl("th", { text: "Duration" })); - for (let entry of tracker.entries) { - let row = table.createEl("tr"); - row.createEl("td", { text: entry.name }); - row.createEl("td", { text: formatTimestamp(entry.startTime, settings) }); - if (entry.endTime) { - row.createEl("td", { text: formatTimestamp(entry.endTime, settings) }); - row.createEl("td", { text: formatDurationBetween(entry.startTime, entry.endTime) }); - } - } - let buttons = element.createEl("div", { cls: "simple-time-tracker-bottom" }); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as table").onClick(() => navigator.clipboard.writeText(createMarkdownTable(tracker, settings))); - new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as CSV").onClick(() => navigator.clipboard.writeText(createCsv(tracker, settings))); - } - setCountdownValues(tracker, current, total, currentDiv); - let intervalId = window.setInterval(() => { - if (!element.isConnected) { - window.clearInterval(intervalId); - return; - } - setCountdownValues(tracker, current, total, currentDiv); - }, 1e3); -} -function setCountdownValues(tracker, current, total, currentDiv) { - let currEntry = tracker.entries.last(); - if (currEntry) { - if (!currEntry.endTime) - current.setText(formatDurationBetween(currEntry.startTime, (0, import_obsidian2.moment)().unix())); - total.setText(formatDuration(getTotalDuration(tracker))); - } - currentDiv.hidden = !currEntry || !!currEntry.endTime; -} -function getTotalDuration(tracker) { - let totalDuration = 0; - for (let entry of tracker.entries) { - let endTime = entry.endTime ? import_obsidian2.moment.unix(entry.endTime) : (0, import_obsidian2.moment)(); - totalDuration += endTime.diff(import_obsidian2.moment.unix(entry.startTime)); - } - return totalDuration; -} -function formatTimestamp(timestamp, settings) { - return import_obsidian2.moment.unix(timestamp).format(settings.timestampFormat); -} -function formatDurationBetween(startTime, endTime) { - return formatDuration(import_obsidian2.moment.unix(endTime).diff(import_obsidian2.moment.unix(startTime))); -} -function formatDuration(totalTime) { - let duration = import_obsidian2.moment.duration(totalTime); - let ret = ""; - if (duration.hours() > 0) - ret += duration.hours() + "h "; - if (duration.minutes() > 0) - ret += duration.minutes() + "m "; - ret += duration.seconds() + "s"; - return ret; -} -function createMarkdownTable(tracker, settings) { - let table = [["Segment", "Start time", "End time", "Duration"]]; - for (let entry of tracker.entries) - table.push(createTableRow(entry, settings)); - table.push(["**Total**", "", "", `**${formatDuration(getTotalDuration(tracker))}**`]); - let ret = ""; - let widths = Array.from(Array(4).keys()).map((i) => Math.max(...table.map((a) => a[i].length))); - for (let r = 0; r < table.length; r++) { - if (r == 1) - ret += Array.from(Array(4).keys()).map((i) => "-".repeat(widths[i])).join(" | ") + "\n"; - let row = []; - for (let i = 0; i < 4; i++) - row.push(table[r][i].padEnd(widths[i], " ")); - ret += row.join(" | ") + "\n"; - } - return ret; -} -function createCsv(tracker, settings) { - let ret = ""; - for (let entry of tracker.entries) - ret += createTableRow(entry, settings).join(settings.csvDelimiter) + "\n"; - return ret; -} -function createTableRow(entry, settings) { - return [ - entry.name, - formatTimestamp(entry.startTime, settings), - entry.endTime ? formatTimestamp(entry.endTime, settings) : "", - entry.endTime ? formatDurationBetween(entry.startTime, entry.endTime) : "" - ]; -} - -// src/main.ts -var SimpleTimeTrackerPlugin = class extends import_obsidian3.Plugin { - onload() { - return __async(this, null, function* () { - yield this.loadSettings(); - this.addSettingTab(new SimpleTimeTrackerSettingsTab(this.app, this)); - this.registerMarkdownCodeBlockProcessor("simple-time-tracker", (s, e, i) => { - let tracker = loadTracker(s); - e.empty(); - displayTracker(tracker, e, () => i.getSectionInfo(e), this.settings); - }); - this.addCommand({ - id: `insert-simple-time-tracker`, - name: `Insert Time Tracker`, - editorCallback: (e, _) => { - e.replaceSelection("```simple-time-tracker\n```\n"); - } - }); - }); - } - loadSettings() { - return __async(this, null, function* () { - this.settings = Object.assign({}, defaultSettings, yield this.loadData()); - }); - } - saveSettings() { - return __async(this, null, function* () { - yield this.saveData(this.settings); - }); - } -}; diff --git a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/data.json b/test-vault/.obsidian/plugins/simple-time-tracker/data.json similarity index 100% rename from test-vault/.obsidian/plugins/obsidian-simple-time-tracker/data.json rename to test-vault/.obsidian/plugins/simple-time-tracker/data.json diff --git a/test-vault/.obsidian/plugins/simple-time-tracker/main.js b/test-vault/.obsidian/plugins/simple-time-tracker/main.js new file mode 100644 index 0000000..a3d1d9a --- /dev/null +++ b/test-vault/.obsidian/plugins/simple-time-tracker/main.js @@ -0,0 +1,275 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); +var __export = (target, all) => { + __markAsModule(target); + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key of __getOwnPropNames(module2)) + if (!__hasOwnProp.call(target, key) && key !== "default") + __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); + } + return target; +}; +var __toModule = (module2) => { + return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); +}; +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e) { + reject(e); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; + +// src/main.ts +__export(exports, { + default: () => SimpleTimeTrackerPlugin +}); +var import_obsidian3 = __toModule(require("obsidian")); + +// src/settings.ts +var defaultSettings = { + timestampFormat: "YY-MM-DD hh:mm:ss", + csvDelimiter: "," +}; + +// src/settings-tab.ts +var import_obsidian = __toModule(require("obsidian")); +var SimpleTimeTrackerSettingsTab = class extends import_obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + display() { + this.containerEl.empty(); + this.containerEl.createEl("h2", { text: "Super Simple Time Tracker Settings" }); + new import_obsidian.Setting(this.containerEl).setName("Timestamp Display Format").setDesc(createFragment((f) => { + f.createSpan({ text: "The way that timestamps in time tracker tables should be displayed. Uses " }); + f.createEl("a", { text: "moment.js", href: "https://momentjs.com/docs/#/parsing/string-format/" }); + f.createSpan({ text: " syntax." }); + })).addText((t) => { + t.setValue(String(this.plugin.settings.timestampFormat)); + t.onChange((v) => __async(this, null, function* () { + this.plugin.settings.timestampFormat = v.length ? v : defaultSettings.timestampFormat; + yield this.plugin.saveSettings(); + })); + }); + new import_obsidian.Setting(this.containerEl).setName("CSV Delimiter").setDesc("The delimiter character that should be used when copying a tracker table as CSV. For example, some languages use a semicolon instead of a comma.").addText((t) => { + t.setValue(String(this.plugin.settings.csvDelimiter)); + t.onChange((v) => __async(this, null, function* () { + this.plugin.settings.csvDelimiter = v.length ? v : defaultSettings.csvDelimiter; + yield this.plugin.saveSettings(); + })); + }); + this.containerEl.createEl("hr"); + this.containerEl.createEl("p", { text: "If you like this plugin and want to support its development, you can do so through my website by clicking this fancy image!" }); + this.containerEl.createEl("a", { href: "https://ellpeck.de/support" }).createEl("img", { attr: { src: "https://ellpeck.de/res/generalsupport.png" }, cls: "simple-time-tracker-support" }); + } +}; + +// src/tracker.ts +var import_obsidian2 = __toModule(require("obsidian")); +function startEntry(tracker, name) { + if (!name) + name = `Segment ${tracker.entries.length + 1}`; + let entry = { name, startTime: (0, import_obsidian2.moment)().unix(), endTime: null }; + tracker.entries.push(entry); +} +function endEntry(tracker) { + let last = tracker.entries.last(); + last.endTime = (0, import_obsidian2.moment)().unix(); +} +function isRunning(tracker) { + let last = tracker.entries.last(); + return last != null && !last.endTime; +} +function saveTracker(tracker, app, section) { + return __async(this, null, function* () { + let file = app.workspace.getActiveFile(); + let content = yield app.vault.cachedRead(file); + let lines = content.split("\n"); + let prev = lines.filter((_, i) => i <= section.lineStart).join("\n"); + let next = lines.filter((_, i) => i >= section.lineEnd).join("\n"); + content = `${prev} +${JSON.stringify(tracker)} +${next}`; + yield app.vault.modify(file, content); + }); +} +function loadTracker(json) { + if (json) { + try { + return JSON.parse(json); + } catch (e) { + console.log(`Failed to parse Tracker from ${json}`); + } + } + return { entries: [] }; +} +function displayTracker(tracker, element, getSectionInfo, settings) { + let running = isRunning(tracker); + let btn = new import_obsidian2.ButtonComponent(element).setButtonText(running ? "End" : "Start").onClick(() => __async(this, null, function* () { + if (running) { + endEntry(tracker); + } else { + startEntry(tracker, name.getValue()); + } + yield saveTracker(tracker, this.app, getSectionInfo()); + })); + btn.buttonEl.addClass("simple-time-tracker-btn"); + let name = new import_obsidian2.TextComponent(element).setPlaceholder("Segment name").setDisabled(running); + name.inputEl.addClass("simple-time-tracker-txt"); + let timer = element.createDiv({ cls: "simple-time-tracker-timers" }); + let currentDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); + let current = currentDiv.createEl("span", { cls: "simple-time-tracker-timer-time" }); + currentDiv.createEl("span", { text: "Current" }); + let totalDiv = timer.createEl("div", { cls: "simple-time-tracker-timer" }); + let total = totalDiv.createEl("span", { cls: "simple-time-tracker-timer-time", text: "0s" }); + totalDiv.createEl("span", { text: "Total" }); + if (tracker.entries.length > 0) { + let table = element.createEl("table", { cls: "simple-time-tracker-table" }); + table.createEl("tr").append(createEl("th", { text: "Segment" }), createEl("th", { text: "Start time" }), createEl("th", { text: "End time" }), createEl("th", { text: "Duration" })); + for (let entry of tracker.entries) { + let row = table.createEl("tr"); + row.createEl("td", { text: entry.name }); + row.createEl("td", { text: formatTimestamp(entry.startTime, settings) }); + if (entry.endTime) { + row.createEl("td", { text: formatTimestamp(entry.endTime, settings) }); + row.createEl("td", { text: formatDurationBetween(entry.startTime, entry.endTime) }); + } + } + let buttons = element.createEl("div", { cls: "simple-time-tracker-bottom" }); + new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as table").onClick(() => navigator.clipboard.writeText(createMarkdownTable(tracker, settings))); + new import_obsidian2.ButtonComponent(buttons).setButtonText("Copy as CSV").onClick(() => navigator.clipboard.writeText(createCsv(tracker, settings))); + } + setCountdownValues(tracker, current, total, currentDiv); + let intervalId = window.setInterval(() => { + if (!element.isConnected) { + window.clearInterval(intervalId); + return; + } + setCountdownValues(tracker, current, total, currentDiv); + }, 1e3); +} +function setCountdownValues(tracker, current, total, currentDiv) { + let currEntry = tracker.entries.last(); + if (currEntry) { + if (!currEntry.endTime) + current.setText(formatDurationBetween(currEntry.startTime, (0, import_obsidian2.moment)().unix())); + total.setText(formatDuration(getTotalDuration(tracker))); + } + currentDiv.hidden = !currEntry || !!currEntry.endTime; +} +function getTotalDuration(tracker) { + let totalDuration = 0; + for (let entry of tracker.entries) { + let endTime = entry.endTime ? import_obsidian2.moment.unix(entry.endTime) : (0, import_obsidian2.moment)(); + totalDuration += endTime.diff(import_obsidian2.moment.unix(entry.startTime)); + } + return totalDuration; +} +function formatTimestamp(timestamp, settings) { + return import_obsidian2.moment.unix(timestamp).format(settings.timestampFormat); +} +function formatDurationBetween(startTime, endTime) { + return formatDuration(import_obsidian2.moment.unix(endTime).diff(import_obsidian2.moment.unix(startTime))); +} +function formatDuration(totalTime) { + let duration = import_obsidian2.moment.duration(totalTime); + let ret = ""; + if (duration.hours() > 0) + ret += duration.hours() + "h "; + if (duration.minutes() > 0) + ret += duration.minutes() + "m "; + ret += duration.seconds() + "s"; + return ret; +} +function createMarkdownTable(tracker, settings) { + let table = [["Segment", "Start time", "End time", "Duration"]]; + for (let entry of tracker.entries) + table.push(createTableRow(entry, settings)); + table.push(["**Total**", "", "", `**${formatDuration(getTotalDuration(tracker))}**`]); + let ret = ""; + let widths = Array.from(Array(4).keys()).map((i) => Math.max(...table.map((a) => a[i].length))); + for (let r = 0; r < table.length; r++) { + if (r == 1) + ret += Array.from(Array(4).keys()).map((i) => "-".repeat(widths[i])).join(" | ") + "\n"; + let row = []; + for (let i = 0; i < 4; i++) + row.push(table[r][i].padEnd(widths[i], " ")); + ret += row.join(" | ") + "\n"; + } + return ret; +} +function createCsv(tracker, settings) { + let ret = ""; + for (let entry of tracker.entries) + ret += createTableRow(entry, settings).join(settings.csvDelimiter) + "\n"; + return ret; +} +function createTableRow(entry, settings) { + return [ + entry.name, + formatTimestamp(entry.startTime, settings), + entry.endTime ? formatTimestamp(entry.endTime, settings) : "", + entry.endTime ? formatDurationBetween(entry.startTime, entry.endTime) : "" + ]; +} + +// src/main.ts +var SimpleTimeTrackerPlugin = class extends import_obsidian3.Plugin { + onload() { + return __async(this, null, function* () { + yield this.loadSettings(); + this.addSettingTab(new SimpleTimeTrackerSettingsTab(this.app, this)); + this.registerMarkdownCodeBlockProcessor("simple-time-tracker", (s, e, i) => { + let tracker = loadTracker(s); + e.empty(); + displayTracker(tracker, e, () => i.getSectionInfo(e), this.settings); + }); + this.addCommand({ + id: `insert`, + name: `Insert Time Tracker`, + editorCallback: (e, _) => { + e.replaceSelection("```simple-time-tracker\n```\n"); + } + }); + }); + } + loadSettings() { + return __async(this, null, function* () { + this.settings = Object.assign({}, defaultSettings, yield this.loadData()); + }); + } + saveSettings() { + return __async(this, null, function* () { + yield this.saveData(this.settings); + }); + } +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3NldHRpbmdzLnRzIiwgInNyYy9zZXR0aW5ncy10YWIudHMiLCAic3JjL3RyYWNrZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IFBsdWdpbiB9IGZyb20gXCJvYnNpZGlhblwiO1xyXG5pbXBvcnQgeyBkZWZhdWx0U2V0dGluZ3MsIFNpbXBsZVRpbWVUcmFja2VyU2V0dGluZ3MgfSBmcm9tIFwiLi9zZXR0aW5nc1wiO1xyXG5pbXBvcnQgeyBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzVGFiIH0gZnJvbSBcIi4vc2V0dGluZ3MtdGFiXCI7XHJcbmltcG9ydCB7IGRpc3BsYXlUcmFja2VyLCBsb2FkVHJhY2tlciB9IGZyb20gXCIuL3RyYWNrZXJcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNpbXBsZVRpbWVUcmFja2VyUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcclxuXHJcblx0c2V0dGluZ3M6IFNpbXBsZVRpbWVUcmFja2VyU2V0dGluZ3M7XHJcblxyXG5cdGFzeW5jIG9ubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XHJcblxyXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzVGFiKHRoaXMuYXBwLCB0aGlzKSk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3Rlck1hcmtkb3duQ29kZUJsb2NrUHJvY2Vzc29yKFwic2ltcGxlLXRpbWUtdHJhY2tlclwiLCAocywgZSwgaSkgPT4ge1xyXG5cdFx0XHRsZXQgdHJhY2tlciA9IGxvYWRUcmFja2VyKHMpO1xyXG5cdFx0XHRlLmVtcHR5KCk7XHJcblx0XHRcdGRpc3BsYXlUcmFja2VyKHRyYWNrZXIsIGUsICgpID0+IGkuZ2V0U2VjdGlvbkluZm8oZSksIHRoaXMuc2V0dGluZ3MpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcclxuXHRcdFx0aWQ6IGBpbnNlcnRgLFxyXG5cdFx0XHRuYW1lOiBgSW5zZXJ0IFRpbWUgVHJhY2tlcmAsXHJcblx0XHRcdGVkaXRvckNhbGxiYWNrOiAoZSwgXykgPT4ge1xyXG5cdFx0XHRcdGUucmVwbGFjZVNlbGVjdGlvbihcImBgYHNpbXBsZS10aW1lLXRyYWNrZXJcXG5gYGBcXG5cIik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xyXG5cdFx0dGhpcy5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRTZXR0aW5ncywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0fVxyXG59XHJcbiIsICJleHBvcnQgY29uc3QgZGVmYXVsdFNldHRpbmdzOiBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzID0ge1xyXG4gICAgdGltZXN0YW1wRm9ybWF0OiBcIllZLU1NLUREIGhoOm1tOnNzXCIsXHJcbiAgICBjc3ZEZWxpbWl0ZXI6IFwiLFwiXHJcbn07XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNpbXBsZVRpbWVUcmFja2VyU2V0dGluZ3Mge1xyXG5cclxuICAgIHRpbWVzdGFtcEZvcm1hdDogc3RyaW5nO1xyXG4gICAgY3N2RGVsaW1pdGVyOiBzdHJpbmc7XHJcblxyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcgfSBmcm9tIFwib2JzaWRpYW5cIjtcclxuaW1wb3J0IFNpbXBsZVRpbWVUcmFja2VyUGx1Z2luIGZyb20gXCIuL21haW5cIjtcclxuaW1wb3J0IHsgZGVmYXVsdFNldHRpbmdzIH0gZnJvbSBcIi4vc2V0dGluZ3NcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblxyXG4gICAgcGx1Z2luOiBTaW1wbGVUaW1lVHJhY2tlclBsdWdpbjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBTaW1wbGVUaW1lVHJhY2tlclBsdWdpbikge1xyXG4gICAgICAgIHN1cGVyKGFwcCwgcGx1Z2luKTtcclxuICAgICAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuICAgIH1cclxuXHJcbiAgICBkaXNwbGF5KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuZW1wdHkoKTtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIlN1cGVyIFNpbXBsZSBUaW1lIFRyYWNrZXIgU2V0dGluZ3NcIiB9KTtcclxuXHJcbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcclxuICAgICAgICAgICAgLnNldE5hbWUoXCJUaW1lc3RhbXAgRGlzcGxheSBGb3JtYXRcIilcclxuICAgICAgICAgICAgLnNldERlc2MoY3JlYXRlRnJhZ21lbnQoZiA9PiB7XHJcbiAgICAgICAgICAgICAgICBmLmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIlRoZSB3YXkgdGhhdCB0aW1lc3RhbXBzIGluIHRpbWUgdHJhY2tlciB0YWJsZXMgc2hvdWxkIGJlIGRpc3BsYXllZC4gVXNlcyBcIiB9KTtcclxuICAgICAgICAgICAgICAgIGYuY3JlYXRlRWwoXCJhXCIsIHsgdGV4dDogXCJtb21lbnQuanNcIiwgaHJlZjogXCJodHRwczovL21vbWVudGpzLmNvbS9kb2NzLyMvcGFyc2luZy9zdHJpbmctZm9ybWF0L1wiIH0pO1xyXG4gICAgICAgICAgICAgICAgZi5jcmVhdGVTcGFuKHsgdGV4dDogXCIgc3ludGF4LlwiIH0pO1xyXG4gICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgLmFkZFRleHQodCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0LnNldFZhbHVlKFN0cmluZyh0aGlzLnBsdWdpbi5zZXR0aW5ncy50aW1lc3RhbXBGb3JtYXQpKTtcclxuICAgICAgICAgICAgICAgIHQub25DaGFuZ2UoYXN5bmMgdiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudGltZXN0YW1wRm9ybWF0ID0gdi5sZW5ndGggPyB2IDogZGVmYXVsdFNldHRpbmdzLnRpbWVzdGFtcEZvcm1hdDtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcclxuICAgICAgICAgICAgLnNldE5hbWUoXCJDU1YgRGVsaW1pdGVyXCIpXHJcbiAgICAgICAgICAgIC5zZXREZXNjKFwiVGhlIGRlbGltaXRlciBjaGFyYWN0ZXIgdGhhdCBzaG91bGQgYmUgdXNlZCB3aGVuIGNvcHlpbmcgYSB0cmFja2VyIHRhYmxlIGFzIENTVi4gRm9yIGV4YW1wbGUsIHNvbWUgbGFuZ3VhZ2VzIHVzZSBhIHNlbWljb2xvbiBpbnN0ZWFkIG9mIGEgY29tbWEuXCIpXHJcbiAgICAgICAgICAgIC5hZGRUZXh0KHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdC5zZXRWYWx1ZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MuY3N2RGVsaW1pdGVyKSk7XHJcbiAgICAgICAgICAgICAgICB0Lm9uQ2hhbmdlKGFzeW5jIHYgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmNzdkRlbGltaXRlciA9IHYubGVuZ3RoID8gdiA6IGRlZmF1bHRTZXR0aW5ncy5jc3ZEZWxpbWl0ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoclwiKTtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwicFwiLCB7IHRleHQ6IFwiSWYgeW91IGxpa2UgdGhpcyBwbHVnaW4gYW5kIHdhbnQgdG8gc3VwcG9ydCBpdHMgZGV2ZWxvcG1lbnQsIHlvdSBjYW4gZG8gc28gdGhyb3VnaCBteSB3ZWJzaXRlIGJ5IGNsaWNraW5nIHRoaXMgZmFuY3kgaW1hZ2UhXCIgfSk7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImFcIiwgeyBocmVmOiBcImh0dHBzOi8vZWxscGVjay5kZS9zdXBwb3J0XCIgfSlcclxuICAgICAgICAgICAgLmNyZWF0ZUVsKFwiaW1nXCIsIHsgYXR0cjogeyBzcmM6IFwiaHR0cHM6Ly9lbGxwZWNrLmRlL3Jlcy9nZW5lcmFsc3VwcG9ydC5wbmdcIiB9LCBjbHM6IFwic2ltcGxlLXRpbWUtdHJhY2tlci1zdXBwb3J0XCIgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwgImltcG9ydCB7IG1vbWVudCwgQXBwLCBNYXJrZG93blNlY3Rpb25JbmZvcm1hdGlvbiwgQnV0dG9uQ29tcG9uZW50LCBUZXh0Q29tcG9uZW50IH0gZnJvbSBcIm9ic2lkaWFuXCI7XHJcbmltcG9ydCB7IFNpbXBsZVRpbWVUcmFja2VyU2V0dGluZ3MgfSBmcm9tIFwiLi9zZXR0aW5nc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRyYWNrZXIge1xyXG4gICAgZW50cmllczogRW50cnlbXTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBFbnRyeSB7XHJcbiAgICBuYW1lOiBzdHJpbmc7XHJcbiAgICBzdGFydFRpbWU6IG51bWJlcjtcclxuICAgIGVuZFRpbWU6IG51bWJlcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0RW50cnkodHJhY2tlcjogVHJhY2tlciwgbmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAoIW5hbWUpXHJcbiAgICAgICAgbmFtZSA9IGBTZWdtZW50ICR7dHJhY2tlci5lbnRyaWVzLmxlbmd0aCArIDF9YDtcclxuICAgIGxldCBlbnRyeTogRW50cnkgPSB7IG5hbWU6IG5hbWUsIHN0YXJ0VGltZTogbW9tZW50KCkudW5peCgpLCBlbmRUaW1lOiBudWxsIH07XHJcbiAgICB0cmFja2VyLmVudHJpZXMucHVzaChlbnRyeSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZW5kRW50cnkodHJhY2tlcjogVHJhY2tlcik6IHZvaWQge1xyXG4gICAgbGV0IGxhc3QgPSB0cmFja2VyLmVudHJpZXMubGFzdCgpO1xyXG4gICAgbGFzdC5lbmRUaW1lID0gbW9tZW50KCkudW5peCgpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNSdW5uaW5nKHRyYWNrZXI6IFRyYWNrZXIpOiBib29sZWFuIHtcclxuICAgIGxldCBsYXN0ID0gdHJhY2tlci5lbnRyaWVzLmxhc3QoKTtcclxuICAgIHJldHVybiBsYXN0ICE9IG51bGwgJiYgIWxhc3QuZW5kVGltZTtcclxufVxyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNhdmVUcmFja2VyKHRyYWNrZXI6IFRyYWNrZXIsIGFwcDogQXBwLCBzZWN0aW9uOiBNYXJrZG93blNlY3Rpb25JbmZvcm1hdGlvbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgbGV0IGZpbGUgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKTtcclxuICAgIGxldCBjb250ZW50ID0gYXdhaXQgYXBwLnZhdWx0LmNhY2hlZFJlYWQoZmlsZSk7XHJcblxyXG4gICAgLy8gZmlndXJlIG91dCB3aGF0IHBhcnQgb2YgdGhlIGNvbnRlbnQgd2UgaGF2ZSB0byBlZGl0XHJcbiAgICBsZXQgbGluZXMgPSBjb250ZW50LnNwbGl0KFwiXFxuXCIpO1xyXG4gICAgbGV0IHByZXYgPSBsaW5lcy5maWx0ZXIoKF8sIGkpID0+IGkgPD0gc2VjdGlvbi5saW5lU3RhcnQpLmpvaW4oXCJcXG5cIik7XHJcbiAgICBsZXQgbmV4dCA9IGxpbmVzLmZpbHRlcigoXywgaSkgPT4gaSA+PSBzZWN0aW9uLmxpbmVFbmQpLmpvaW4oXCJcXG5cIik7XHJcbiAgICAvLyBlZGl0IG9ubHkgdGhlIGNvZGUgYmxvY2sgY29udGVudCwgbGVhdmUgdGhlIHJlc3QgdW50b3VjaGVkXHJcbiAgICBjb250ZW50ID0gYCR7cHJldn1cXG4ke0pTT04uc3RyaW5naWZ5KHRyYWNrZXIpfVxcbiR7bmV4dH1gO1xyXG5cclxuICAgIGF3YWl0IGFwcC52YXVsdC5tb2RpZnkoZmlsZSwgY29udGVudCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBsb2FkVHJhY2tlcihqc29uOiBzdHJpbmcpOiBUcmFja2VyIHtcclxuICAgIGlmIChqc29uKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoanNvbik7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgRmFpbGVkIHRvIHBhcnNlIFRyYWNrZXIgZnJvbSAke2pzb259YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHsgZW50cmllczogW10gfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpc3BsYXlUcmFja2VyKHRyYWNrZXI6IFRyYWNrZXIsIGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBnZXRTZWN0aW9uSW5mbzogKCkgPT4gTWFya2Rvd25TZWN0aW9uSW5mb3JtYXRpb24sIHNldHRpbmdzOiBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzKTogdm9pZCB7XHJcbiAgICAvLyBhZGQgc3RhcnQvc3RvcCBjb250cm9sc1xyXG4gICAgbGV0IHJ1bm5pbmcgPSBpc1J1bm5pbmcodHJhY2tlcik7XHJcbiAgICBsZXQgYnRuID0gbmV3IEJ1dHRvbkNvbXBvbmVudChlbGVtZW50KVxyXG4gICAgICAgIC5zZXRCdXR0b25UZXh0KHJ1bm5pbmcgPyBcIkVuZFwiIDogXCJTdGFydFwiKVxyXG4gICAgICAgIC5vbkNsaWNrKGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHJ1bm5pbmcpIHtcclxuICAgICAgICAgICAgICAgIGVuZEVudHJ5KHRyYWNrZXIpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc3RhcnRFbnRyeSh0cmFja2VyLCBuYW1lLmdldFZhbHVlKCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGF3YWl0IHNhdmVUcmFja2VyKHRyYWNrZXIsIHRoaXMuYXBwLCBnZXRTZWN0aW9uSW5mbygpKTtcclxuICAgICAgICB9KTtcclxuICAgIGJ0bi5idXR0b25FbC5hZGRDbGFzcyhcInNpbXBsZS10aW1lLXRyYWNrZXItYnRuXCIpO1xyXG4gICAgbGV0IG5hbWUgPSBuZXcgVGV4dENvbXBvbmVudChlbGVtZW50KVxyXG4gICAgICAgIC5zZXRQbGFjZWhvbGRlcihcIlNlZ21lbnQgbmFtZVwiKVxyXG4gICAgICAgIC5zZXREaXNhYmxlZChydW5uaW5nKTtcclxuICAgIG5hbWUuaW5wdXRFbC5hZGRDbGFzcyhcInNpbXBsZS10aW1lLXRyYWNrZXItdHh0XCIpO1xyXG5cclxuICAgIC8vIGFkZCB0aW1lcnNcclxuICAgIGxldCB0aW1lciA9IGVsZW1lbnQuY3JlYXRlRGl2KHsgY2xzOiBcInNpbXBsZS10aW1lLXRyYWNrZXItdGltZXJzXCIgfSk7XHJcbiAgICBsZXQgY3VycmVudERpdiA9IHRpbWVyLmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNpbXBsZS10aW1lLXRyYWNrZXItdGltZXJcIiB9KTtcclxuICAgIGxldCBjdXJyZW50ID0gY3VycmVudERpdi5jcmVhdGVFbChcInNwYW5cIiwgeyBjbHM6IFwic2ltcGxlLXRpbWUtdHJhY2tlci10aW1lci10aW1lXCIgfSk7XHJcbiAgICBjdXJyZW50RGl2LmNyZWF0ZUVsKFwic3BhblwiLCB7IHRleHQ6IFwiQ3VycmVudFwiIH0pO1xyXG4gICAgbGV0IHRvdGFsRGl2ID0gdGltZXIuY3JlYXRlRWwoXCJkaXZcIiwgeyBjbHM6IFwic2ltcGxlLXRpbWUtdHJhY2tlci10aW1lclwiIH0pO1xyXG4gICAgbGV0IHRvdGFsID0gdG90YWxEaXYuY3JlYXRlRWwoXCJzcGFuXCIsIHsgY2xzOiBcInNpbXBsZS10aW1lLXRyYWNrZXItdGltZXItdGltZVwiLCB0ZXh0OiBcIjBzXCIgfSk7XHJcbiAgICB0b3RhbERpdi5jcmVhdGVFbChcInNwYW5cIiwgeyB0ZXh0OiBcIlRvdGFsXCIgfSk7XHJcblxyXG4gICAgaWYgKHRyYWNrZXIuZW50cmllcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgLy8gYWRkIHRhYmxlXHJcbiAgICAgICAgbGV0IHRhYmxlID0gZWxlbWVudC5jcmVhdGVFbChcInRhYmxlXCIsIHsgY2xzOiBcInNpbXBsZS10aW1lLXRyYWNrZXItdGFibGVcIiB9KTtcclxuICAgICAgICB0YWJsZS5jcmVhdGVFbChcInRyXCIpLmFwcGVuZChcclxuICAgICAgICAgICAgY3JlYXRlRWwoXCJ0aFwiLCB7IHRleHQ6IFwiU2VnbWVudFwiIH0pLFxyXG4gICAgICAgICAgICBjcmVhdGVFbChcInRoXCIsIHsgdGV4dDogXCJTdGFydCB0aW1lXCIgfSksXHJcbiAgICAgICAgICAgIGNyZWF0ZUVsKFwidGhcIiwgeyB0ZXh0OiBcIkVuZCB0aW1lXCIgfSksXHJcbiAgICAgICAgICAgIGNyZWF0ZUVsKFwidGhcIiwgeyB0ZXh0OiBcIkR1cmF0aW9uXCIgfSkpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiB0cmFja2VyLmVudHJpZXMpIHtcclxuICAgICAgICAgICAgbGV0IHJvdyA9IHRhYmxlLmNyZWF0ZUVsKFwidHJcIik7XHJcbiAgICAgICAgICAgIHJvdy5jcmVhdGVFbChcInRkXCIsIHsgdGV4dDogZW50cnkubmFtZSB9KTtcclxuICAgICAgICAgICAgcm93LmNyZWF0ZUVsKFwidGRcIiwgeyB0ZXh0OiBmb3JtYXRUaW1lc3RhbXAoZW50cnkuc3RhcnRUaW1lLCBzZXR0aW5ncykgfSk7XHJcbiAgICAgICAgICAgIGlmIChlbnRyeS5lbmRUaW1lKSB7XHJcbiAgICAgICAgICAgICAgICByb3cuY3JlYXRlRWwoXCJ0ZFwiLCB7IHRleHQ6IGZvcm1hdFRpbWVzdGFtcChlbnRyeS5lbmRUaW1lLCBzZXR0aW5ncykgfSk7XHJcbiAgICAgICAgICAgICAgICByb3cuY3JlYXRlRWwoXCJ0ZFwiLCB7IHRleHQ6IGZvcm1hdER1cmF0aW9uQmV0d2VlbihlbnRyeS5zdGFydFRpbWUsIGVudHJ5LmVuZFRpbWUpIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBhZGQgY29weSBidXR0b25zXHJcbiAgICAgICAgbGV0IGJ1dHRvbnMgPSBlbGVtZW50LmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNpbXBsZS10aW1lLXRyYWNrZXItYm90dG9tXCIgfSk7XHJcbiAgICAgICAgbmV3IEJ1dHRvbkNvbXBvbmVudChidXR0b25zKVxyXG4gICAgICAgICAgICAuc2V0QnV0dG9uVGV4dChcIkNvcHkgYXMgdGFibGVcIilcclxuICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4gbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoY3JlYXRlTWFya2Rvd25UYWJsZSh0cmFja2VyLCBzZXR0aW5ncykpKTtcclxuICAgICAgICBuZXcgQnV0dG9uQ29tcG9uZW50KGJ1dHRvbnMpXHJcbiAgICAgICAgICAgIC5zZXRCdXR0b25UZXh0KFwiQ29weSBhcyBDU1ZcIilcclxuICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4gbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoY3JlYXRlQ3N2KHRyYWNrZXIsIHNldHRpbmdzKSkpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBzZXRDb3VudGRvd25WYWx1ZXModHJhY2tlciwgY3VycmVudCwgdG90YWwsIGN1cnJlbnREaXYpO1xyXG4gICAgbGV0IGludGVydmFsSWQgPSB3aW5kb3cuc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG4gICAgICAgIC8vIHdlIGRlbGV0ZSB0aGUgaW50ZXJ2YWwgdGltZXIgd2hlbiB0aGUgZWxlbWVudCBpcyByZW1vdmVkXHJcbiAgICAgICAgaWYgKCFlbGVtZW50LmlzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKGludGVydmFsSWQpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNldENvdW50ZG93blZhbHVlcyh0cmFja2VyLCBjdXJyZW50LCB0b3RhbCwgY3VycmVudERpdik7XHJcbiAgICB9LCAxMDAwKTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2V0Q291bnRkb3duVmFsdWVzKHRyYWNrZXI6IFRyYWNrZXIsIGN1cnJlbnQ6IEhUTUxFbGVtZW50LCB0b3RhbDogSFRNTEVsZW1lbnQsIGN1cnJlbnREaXY6IEhUTUxEaXZFbGVtZW50KSB7XHJcbiAgICBsZXQgY3VyckVudHJ5ID0gdHJhY2tlci5lbnRyaWVzLmxhc3QoKTtcclxuICAgIGlmIChjdXJyRW50cnkpIHtcclxuICAgICAgICBpZiAoIWN1cnJFbnRyeS5lbmRUaW1lKVxyXG4gICAgICAgICAgICBjdXJyZW50LnNldFRleHQoZm9ybWF0RHVyYXRpb25CZXR3ZWVuKGN1cnJFbnRyeS5zdGFydFRpbWUsIG1vbWVudCgpLnVuaXgoKSkpO1xyXG4gICAgICAgIHRvdGFsLnNldFRleHQoZm9ybWF0RHVyYXRpb24oZ2V0VG90YWxEdXJhdGlvbih0cmFja2VyKSkpO1xyXG4gICAgfVxyXG4gICAgY3VycmVudERpdi5oaWRkZW4gPSAhY3VyckVudHJ5IHx8ICEhY3VyckVudHJ5LmVuZFRpbWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRvdGFsRHVyYXRpb24odHJhY2tlcjogVHJhY2tlcik6IG51bWJlciB7XHJcbiAgICBsZXQgdG90YWxEdXJhdGlvbiA9IDA7XHJcbiAgICBmb3IgKGxldCBlbnRyeSBvZiB0cmFja2VyLmVudHJpZXMpIHtcclxuICAgICAgICBsZXQgZW5kVGltZSA9IGVudHJ5LmVuZFRpbWUgPyBtb21lbnQudW5peChlbnRyeS5lbmRUaW1lKSA6IG1vbWVudCgpO1xyXG4gICAgICAgIHRvdGFsRHVyYXRpb24gKz0gZW5kVGltZS5kaWZmKG1vbWVudC51bml4KGVudHJ5LnN0YXJ0VGltZSkpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvdGFsRHVyYXRpb247XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZvcm1hdFRpbWVzdGFtcCh0aW1lc3RhbXA6IG51bWJlciwgc2V0dGluZ3M6IFNpbXBsZVRpbWVUcmFja2VyU2V0dGluZ3MpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIG1vbWVudC51bml4KHRpbWVzdGFtcCkuZm9ybWF0KHNldHRpbmdzLnRpbWVzdGFtcEZvcm1hdCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZvcm1hdER1cmF0aW9uQmV0d2VlbihzdGFydFRpbWU6IG51bWJlciwgZW5kVGltZTogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBmb3JtYXREdXJhdGlvbihtb21lbnQudW5peChlbmRUaW1lKS5kaWZmKG1vbWVudC51bml4KHN0YXJ0VGltZSkpKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZm9ybWF0RHVyYXRpb24odG90YWxUaW1lOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgbGV0IGR1cmF0aW9uID0gbW9tZW50LmR1cmF0aW9uKHRvdGFsVGltZSk7XHJcbiAgICBsZXQgcmV0ID0gXCJcIjtcclxuICAgIGlmIChkdXJhdGlvbi5ob3VycygpID4gMClcclxuICAgICAgICByZXQgKz0gZHVyYXRpb24uaG91cnMoKSArIFwiaCBcIjtcclxuICAgIGlmIChkdXJhdGlvbi5taW51dGVzKCkgPiAwKVxyXG4gICAgICAgIHJldCArPSBkdXJhdGlvbi5taW51dGVzKCkgKyBcIm0gXCI7XHJcbiAgICByZXQgKz0gZHVyYXRpb24uc2Vjb25kcygpICsgXCJzXCI7XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVNYXJrZG93blRhYmxlKHRyYWNrZXI6IFRyYWNrZXIsIHNldHRpbmdzOiBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzKTogc3RyaW5nIHtcclxuICAgIGxldCB0YWJsZSA9IFtbXCJTZWdtZW50XCIsIFwiU3RhcnQgdGltZVwiLCBcIkVuZCB0aW1lXCIsIFwiRHVyYXRpb25cIl1dO1xyXG4gICAgZm9yIChsZXQgZW50cnkgb2YgdHJhY2tlci5lbnRyaWVzKVxyXG4gICAgICAgIHRhYmxlLnB1c2goY3JlYXRlVGFibGVSb3coZW50cnksIHNldHRpbmdzKSk7XHJcbiAgICB0YWJsZS5wdXNoKFtcIioqVG90YWwqKlwiLCBcIlwiLCBcIlwiLCBgKioke2Zvcm1hdER1cmF0aW9uKGdldFRvdGFsRHVyYXRpb24odHJhY2tlcikpfSoqYF0pO1xyXG5cclxuICAgIGxldCByZXQgPSBcIlwiO1xyXG4gICAgLy8gY2FsY3VsYXRlIHRoZSB3aWR0aCBldmVyeSBjb2x1bW4gbmVlZHMgdG8gbG9vayBuZWF0IHdoZW4gbW9ub3NwYWNlZFxyXG4gICAgbGV0IHdpZHRocyA9IEFycmF5LmZyb20oQXJyYXkoNCkua2V5cygpKS5tYXAoaSA9PiBNYXRoLm1heCguLi50YWJsZS5tYXAoYSA9PiBhW2ldLmxlbmd0aCkpKTtcclxuICAgIGZvciAobGV0IHIgPSAwOyByIDwgdGFibGUubGVuZ3RoOyByKyspIHtcclxuICAgICAgICAvLyBhZGQgc2VwYXJhdG9ycyBhZnRlciBmaXJzdCByb3dcclxuICAgICAgICBpZiAociA9PSAxKVxyXG4gICAgICAgICAgICByZXQgKz0gQXJyYXkuZnJvbShBcnJheSg0KS5rZXlzKCkpLm1hcChpID0+IFwiLVwiLnJlcGVhdCh3aWR0aHNbaV0pKS5qb2luKFwiIHwgXCIpICsgXCJcXG5cIjtcclxuXHJcbiAgICAgICAgbGV0IHJvdzogc3RyaW5nW10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKylcclxuICAgICAgICAgICAgcm93LnB1c2godGFibGVbcl1baV0ucGFkRW5kKHdpZHRoc1tpXSwgXCIgXCIpKTtcclxuICAgICAgICByZXQgKz0gcm93LmpvaW4oXCIgfCBcIikgKyBcIlxcblwiO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJldDtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlQ3N2KHRyYWNrZXI6IFRyYWNrZXIsIHNldHRpbmdzOiBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzKTogc3RyaW5nIHtcclxuICAgIGxldCByZXQgPSBcIlwiO1xyXG4gICAgZm9yIChsZXQgZW50cnkgb2YgdHJhY2tlci5lbnRyaWVzKVxyXG4gICAgICAgIHJldCArPSBjcmVhdGVUYWJsZVJvdyhlbnRyeSwgc2V0dGluZ3MpLmpvaW4oc2V0dGluZ3MuY3N2RGVsaW1pdGVyKSArIFwiXFxuXCI7XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVUYWJsZVJvdyhlbnRyeTogRW50cnksIHNldHRpbmdzOiBTaW1wbGVUaW1lVHJhY2tlclNldHRpbmdzKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICBlbnRyeS5uYW1lLFxyXG4gICAgICAgIGZvcm1hdFRpbWVzdGFtcChlbnRyeS5zdGFydFRpbWUsIHNldHRpbmdzKSxcclxuICAgICAgICBlbnRyeS5lbmRUaW1lID8gZm9ybWF0VGltZXN0YW1wKGVudHJ5LmVuZFRpbWUsIHNldHRpbmdzKSA6IFwiXCIsXHJcbiAgICAgICAgZW50cnkuZW5kVGltZSA/IGZvcm1hdER1cmF0aW9uQmV0d2VlbihlbnRyeS5zdGFydFRpbWUsIGVudHJ5LmVuZFRpbWUpIDogXCJcIl07XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBLHVCQUF1Qjs7O0FDQWhCLElBQU0s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 diff --git a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/manifest.json b/test-vault/.obsidian/plugins/simple-time-tracker/manifest.json similarity index 85% rename from test-vault/.obsidian/plugins/obsidian-simple-time-tracker/manifest.json rename to test-vault/.obsidian/plugins/simple-time-tracker/manifest.json index 514dc0c..5c426fd 100644 --- a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/manifest.json +++ b/test-vault/.obsidian/plugins/simple-time-tracker/manifest.json @@ -1,5 +1,5 @@ { - "id": "obsidian-simple-time-tracker", + "id": "simple-time-tracker", "name": "Super Simple Time Tracker", "version": "0.1.1", "minAppVersion": "0.15.0", diff --git a/test-vault/.obsidian/plugins/obsidian-simple-time-tracker/styles.css b/test-vault/.obsidian/plugins/simple-time-tracker/styles.css similarity index 100% rename from test-vault/.obsidian/plugins/obsidian-simple-time-tracker/styles.css rename to test-vault/.obsidian/plugins/simple-time-tracker/styles.css diff --git a/test-vault/Cool Project.md b/test-vault/Cool Project.md index aecff0f..bf62ae8 100644 --- a/test-vault/Cool Project.md +++ b/test-vault/Cool Project.md @@ -2,7 +2,7 @@ These are the notes for my cool project. There's so much left to do! I wish I had a way to track the amount of time I spend on each part of the project. ```simple-time-tracker -{"entries":[{"name":"Think about project","startTime":1664305777,"endTime":1664308788},{"name":"Create project note","startTime":1664308810,"endTime":1664308815},{"name":"Work on project","startTime":1664308830,"endTime":1664309301},{"name":"Segment 4","startTime":1664364444,"endTime":1664364449},{"name":"Segment 5","startTime":1664364495,"endTime":1664364498}]} +{"entries":[{"name":"Think about project","startTime":1664305777,"endTime":1664308788},{"name":"Create project note","startTime":1664308810,"endTime":1664308815},{"name":"Work on project","startTime":1664308830,"endTime":1664309301},{"name":"Segment 4","startTime":1664364444,"endTime":1664364449},{"name":"Segment 5","startTime":1664364495,"endTime":1664364498},{"name":"Segment 6","startTime":1664458520,"endTime":1664458523}]} ``` ```