mirror of
https://github.com/Ellpeck/ObsidianSimpleTimeTracker.git
synced 2024-11-27 11:38:34 +01:00
Compare commits
9 commits
3be8d8de02
...
51d1183c0f
Author | SHA1 | Date | |
---|---|---|---|
51d1183c0f | |||
17471e2831 | |||
e95f62fb9d | |||
f766fa7210 | |||
|
a6727bb879 | ||
|
3d9e6163e7 | ||
|
0612a4bd21 | ||
|
5677e02243 | ||
|
94631bc293 |
10 changed files with 144 additions and 43 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -12,6 +12,9 @@ node_modules
|
||||||
# They should be uploaded to GitHub releases instead.
|
# They should be uploaded to GitHub releases instead.
|
||||||
/main.js
|
/main.js
|
||||||
|
|
||||||
|
# Exclude local settings
|
||||||
|
data.json
|
||||||
|
|
||||||
# Exclude sourcemaps
|
# Exclude sourcemaps
|
||||||
*.map
|
*.map
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "simple-time-tracker",
|
"id": "simple-time-tracker",
|
||||||
"name": "Super Simple Time Tracker",
|
"name": "Super Simple Time Tracker",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"minAppVersion": "1.2.8",
|
"minAppVersion": "1.2.8",
|
||||||
"description": "Multi-purpose time trackers for your notes!",
|
"description": "Multi-purpose time trackers for your notes!",
|
||||||
"author": "Ellpeck",
|
"author": "Ellpeck",
|
||||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "simple-time-tracker",
|
"name": "simple-time-tracker",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "simple-time-tracker",
|
"name": "simple-time-tracker",
|
||||||
"version": "0.1.6",
|
"version": "0.1.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^16.11.6",
|
"@types/node": "^16.11.6",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "simple-time-tracker",
|
"name": "simple-time-tracker",
|
||||||
"version": "0.1.7",
|
"version": "0.1.8",
|
||||||
"description": "Multi-purpose time trackers for your notes!",
|
"description": "Multi-purpose time trackers for your notes!",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export const defaultSettings: SimpleTimeTrackerSettings = {
|
export const defaultSettings: SimpleTimeTrackerSettings = {
|
||||||
timestampFormat: "YY-MM-DD hh:mm:ss",
|
timestampFormat: "YY-MM-DD HH:mm:ss",
|
||||||
|
editableTimestampFormat: "YYYY-MM-DD HH:mm:ss",
|
||||||
csvDelimiter: ",",
|
csvDelimiter: ",",
|
||||||
fineGrainedDurations: true
|
fineGrainedDurations: true
|
||||||
};
|
};
|
||||||
|
@ -7,6 +8,7 @@ export const defaultSettings: SimpleTimeTrackerSettings = {
|
||||||
export interface SimpleTimeTrackerSettings {
|
export interface SimpleTimeTrackerSettings {
|
||||||
|
|
||||||
timestampFormat: string;
|
timestampFormat: string;
|
||||||
|
editableTimestampFormat: string;
|
||||||
csvDelimiter: string;
|
csvDelimiter: string;
|
||||||
fineGrainedDurations: boolean;
|
fineGrainedDurations: boolean;
|
||||||
|
|
||||||
|
|
155
src/tracker.ts
155
src/tracker.ts
|
@ -1,5 +1,5 @@
|
||||||
import { moment, App, MarkdownSectionInformation, ButtonComponent, TextComponent, TFile } from "obsidian";
|
import {moment, App, MarkdownSectionInformation, ButtonComponent, TextComponent, TFile} from "obsidian";
|
||||||
import { SimpleTimeTrackerSettings } from "./settings";
|
import {SimpleTimeTrackerSettings} from "./settings";
|
||||||
|
|
||||||
export interface Tracker {
|
export interface Tracker {
|
||||||
entries: Entry[];
|
entries: Entry[];
|
||||||
|
@ -7,8 +7,8 @@ export interface Tracker {
|
||||||
|
|
||||||
export interface Entry {
|
export interface Entry {
|
||||||
name: string;
|
name: string;
|
||||||
startTime: number;
|
startTime: string;
|
||||||
endTime: number;
|
endTime: string;
|
||||||
subEntries: Entry[];
|
subEntries: Entry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ export async function saveTracker(tracker: Tracker, app: App, fileName: string,
|
||||||
export function loadTracker(json: string): Tracker {
|
export function loadTracker(json: string): Tracker {
|
||||||
if (json) {
|
if (json) {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(json);
|
let ret = JSON.parse(json);
|
||||||
|
fixLegacyTimestamps(ret.entries);
|
||||||
|
return ret;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`Failed to parse Tracker from ${json}`);
|
console.log(`Failed to parse Tracker from ${json}`);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +42,7 @@ export function loadTracker(json: string): Tracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function displayTracker(tracker: Tracker, element: HTMLElement, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings): void {
|
export function displayTracker(tracker: Tracker, element: HTMLElement, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings): void {
|
||||||
|
element.classList.add("simple-time-tracker-container");
|
||||||
// add start/stop controls
|
// add start/stop controls
|
||||||
let running = isRunning(tracker);
|
let running = isRunning(tracker);
|
||||||
let btn = new ButtonComponent(element)
|
let btn = new ButtonComponent(element)
|
||||||
|
@ -104,7 +107,7 @@ export function displayTracker(tracker: Tracker, element: HTMLElement, file: str
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startSubEntry(entry: Entry, name: string) {
|
function startSubEntry(entry: Entry, name: string): void {
|
||||||
// if this entry is not split yet, we add its time as a sub-entry instead
|
// if this entry is not split yet, we add its time as a sub-entry instead
|
||||||
if (!entry.subEntries) {
|
if (!entry.subEntries) {
|
||||||
entry.subEntries = [{...entry, name: `Part 1`}];
|
entry.subEntries = [{...entry, name: `Part 1`}];
|
||||||
|
@ -114,19 +117,19 @@ function startSubEntry(entry: Entry, name: string) {
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
name = `Part ${entry.subEntries.length + 1}`;
|
name = `Part ${entry.subEntries.length + 1}`;
|
||||||
entry.subEntries.push({name: name, startTime: moment().unix(), endTime: null, subEntries: null});
|
entry.subEntries.push({name: name, startTime: moment().toISOString(), endTime: null, subEntries: null});
|
||||||
}
|
}
|
||||||
|
|
||||||
function startNewEntry(tracker: Tracker, name: string): void {
|
function startNewEntry(tracker: Tracker, name: string): void {
|
||||||
if (!name)
|
if (!name)
|
||||||
name = `Segment ${tracker.entries.length + 1}`;
|
name = `Segment ${tracker.entries.length + 1}`;
|
||||||
let entry: Entry = {name: name, startTime: moment().unix(), endTime: null, subEntries: null};
|
let entry: Entry = {name: name, startTime: moment().toISOString(), endTime: null, subEntries: null};
|
||||||
tracker.entries.push(entry);
|
tracker.entries.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
function endRunningEntry(tracker: Tracker): void {
|
function endRunningEntry(tracker: Tracker): void {
|
||||||
let entry = getRunningEntry(tracker.entries);
|
let entry = getRunningEntry(tracker.entries);
|
||||||
entry.endTime = moment().unix();
|
entry.endTime = moment().toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeEntry(entries: Entry[], toRemove: Entry): boolean {
|
function removeEntry(entries: Entry[], toRemove: Entry): boolean {
|
||||||
|
@ -170,12 +173,12 @@ function getRunningEntry(entries: Entry[]): Entry {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDuration(entry: Entry) {
|
function getDuration(entry: Entry): number {
|
||||||
if (entry.subEntries) {
|
if (entry.subEntries) {
|
||||||
return getTotalDuration(entry.subEntries);
|
return getTotalDuration(entry.subEntries);
|
||||||
} else {
|
} else {
|
||||||
let endTime = entry.endTime ? moment.unix(entry.endTime) : moment();
|
let endTime = entry.endTime ? moment(entry.endTime) : moment();
|
||||||
return endTime.diff(moment.unix(entry.startTime));
|
return endTime.diff(moment(entry.startTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +189,7 @@ function getTotalDuration(entries: Entry[]): number {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCountdownValues(tracker: Tracker, current: HTMLElement, total: HTMLElement, currentDiv: HTMLDivElement, settings: SimpleTimeTrackerSettings) {
|
function setCountdownValues(tracker: Tracker, current: HTMLElement, total: HTMLElement, currentDiv: HTMLDivElement, settings: SimpleTimeTrackerSettings): void {
|
||||||
let running = getRunningEntry(tracker.entries);
|
let running = getRunningEntry(tracker.entries);
|
||||||
if (running && !running.endTime) {
|
if (running && !running.endTime) {
|
||||||
current.setText(formatDuration(getDuration(running), settings));
|
current.setText(formatDuration(getDuration(running), settings));
|
||||||
|
@ -197,8 +200,16 @@ function setCountdownValues(tracker: Tracker, current: HTMLElement, total: HTMLE
|
||||||
total.setText(formatDuration(getTotalDuration(tracker.entries), settings));
|
total.setText(formatDuration(getTotalDuration(tracker.entries), settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTimestamp(timestamp: number, settings: SimpleTimeTrackerSettings): string {
|
function formatTimestamp(timestamp: string, settings: SimpleTimeTrackerSettings): string {
|
||||||
return moment.unix(timestamp).format(settings.timestampFormat);
|
return moment(timestamp).format(settings.timestampFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatEditableTimestamp(timestamp: string, settings: SimpleTimeTrackerSettings): string {
|
||||||
|
return moment(timestamp).format(settings.editableTimestampFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unformatEditableTimestamp(formatted: string, settings: SimpleTimeTrackerSettings): string {
|
||||||
|
return moment(formatted, settings.editableTimestampFormat).toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDuration(totalTime: number, settings: SimpleTimeTrackerSettings): string {
|
function formatDuration(totalTime: number, settings: SimpleTimeTrackerSettings): string {
|
||||||
|
@ -224,6 +235,18 @@ function formatDuration(totalTime: number, settings: SimpleTimeTrackerSettings):
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fixLegacyTimestamps(entries: Entry[]): void {
|
||||||
|
for (let entry of entries) {
|
||||||
|
if (!isNaN(+entry.startTime))
|
||||||
|
entry.startTime = moment.unix(+entry.startTime).toISOString();
|
||||||
|
if (entry.endTime && !isNaN(+entry.endTime))
|
||||||
|
entry.endTime = moment.unix(+entry.endTime).toISOString();
|
||||||
|
|
||||||
|
if (entry.subEntries)
|
||||||
|
fixLegacyTimestamps(entry.subEntries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createMarkdownTable(tracker: Tracker, settings: SimpleTimeTrackerSettings): string {
|
function createMarkdownTable(tracker: Tracker, settings: SimpleTimeTrackerSettings): string {
|
||||||
let table = [["Segment", "Start time", "End time", "Duration"]];
|
let table = [["Segment", "Start time", "End time", "Duration"]];
|
||||||
for (let entry of tracker.entries)
|
for (let entry of tracker.entries)
|
||||||
|
@ -256,7 +279,7 @@ function createCsv(tracker: Tracker, settings: SimpleTimeTrackerSettings): strin
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTableSection(entry: Entry, settings: SimpleTimeTrackerSettings): string[][] {
|
function createTableSection(entry: Entry, settings: SimpleTimeTrackerSettings): string[][] {
|
||||||
let ret: string[][] = [[
|
let ret = [[
|
||||||
entry.name,
|
entry.name,
|
||||||
entry.startTime ? formatTimestamp(entry.startTime, settings) : "",
|
entry.startTime ? formatTimestamp(entry.startTime, settings) : "",
|
||||||
entry.endTime ? formatTimestamp(entry.endTime, settings) : "",
|
entry.endTime ? formatTimestamp(entry.endTime, settings) : "",
|
||||||
|
@ -268,17 +291,80 @@ function createTableSection(entry: Entry, settings: SimpleTimeTrackerSettings):
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, running: boolean, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number) {
|
class EditableField {
|
||||||
|
cell: HTMLTableCellElement;
|
||||||
|
label: HTMLSpanElement;
|
||||||
|
box: TextComponent;
|
||||||
|
|
||||||
|
constructor(row: HTMLTableRowElement, indent: number, value: string) {
|
||||||
|
this.cell = row.createEl("td");
|
||||||
|
this.label = this.cell.createEl("span", {text: value});
|
||||||
|
this.label.style.marginLeft = `${indent}em`;
|
||||||
|
this.box = new TextComponent(this.cell).setValue(value);
|
||||||
|
this.box.inputEl.classList.add("simple-time-tracker-input");
|
||||||
|
this.box.inputEl.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
editing(): boolean {
|
||||||
|
return this.label.hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginEdit(value: string): void {
|
||||||
|
this.label.hidden = true;
|
||||||
|
this.box.setValue(value);
|
||||||
|
this.box.inputEl.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
endEdit(): string {
|
||||||
|
const value = this.box.getValue();
|
||||||
|
this.label.setText(value);
|
||||||
|
this.box.inputEl.hide();
|
||||||
|
this.label.hidden = false;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditableTimestampField extends EditableField {
|
||||||
|
settings: SimpleTimeTrackerSettings;
|
||||||
|
|
||||||
|
constructor(row: HTMLTableRowElement, indent: number, value: string, settings: SimpleTimeTrackerSettings) {
|
||||||
|
super(row, indent, value ? formatTimestamp(value, settings) : "");
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginEdit(value: string): void {
|
||||||
|
super.beginEdit(value ? formatEditableTimestamp(value, this.settings) : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
endEdit(): string {
|
||||||
|
const value = this.box.getValue();
|
||||||
|
let displayValue = value;
|
||||||
|
if (value) {
|
||||||
|
const timestamp = unformatEditableTimestamp(value, this.settings);
|
||||||
|
displayValue = formatTimestamp(timestamp, this.settings);
|
||||||
|
}
|
||||||
|
this.label.setText(displayValue);
|
||||||
|
this.box.inputEl.hide();
|
||||||
|
this.label.hidden = false;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTimestamp(): string {
|
||||||
|
if (this.box.getValue()) {
|
||||||
|
return unformatEditableTimestamp(this.box.getValue(), this.settings);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableElement, newSegmentNameBox: TextComponent, running: boolean, file: string, getSectionInfo: () => MarkdownSectionInformation, settings: SimpleTimeTrackerSettings, indent: number): void {
|
||||||
let row = table.createEl("tr");
|
let row = table.createEl("tr");
|
||||||
|
|
||||||
let name = row.createEl("td");
|
let nameField = new EditableField(row, indent, entry.name);
|
||||||
let namePar = name.createEl("span", {text: entry.name});
|
let startField = new EditableTimestampField(row, indent, (entry.startTime), settings);
|
||||||
namePar.style.marginLeft = `${indent}em`;
|
let endField = new EditableTimestampField(row, indent, (entry.endTime), settings);
|
||||||
let nameBox = new TextComponent(name).setValue(entry.name);
|
|
||||||
nameBox.inputEl.hidden = true;
|
|
||||||
|
|
||||||
row.createEl("td", {text: entry.startTime ? formatTimestamp(entry.startTime, settings) : ""});
|
|
||||||
row.createEl("td", {text: entry.endTime ? formatTimestamp(entry.endTime, settings) : ""});
|
|
||||||
row.createEl("td", {text: entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : ""});
|
row.createEl("td", {text: entry.endTime || entry.subEntries ? formatDuration(getDuration(entry), settings) : ""});
|
||||||
|
|
||||||
let entryButtons = row.createEl("td");
|
let entryButtons = row.createEl("td");
|
||||||
|
@ -297,19 +383,18 @@ function addEditableTableRow(tracker: Tracker, entry: Entry, table: HTMLTableEle
|
||||||
.setTooltip("Edit")
|
.setTooltip("Edit")
|
||||||
.setIcon("lucide-pencil")
|
.setIcon("lucide-pencil")
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
if (namePar.hidden) {
|
if (nameField.editing()) {
|
||||||
namePar.hidden = false;
|
entry.name = nameField.endEdit();
|
||||||
nameBox.inputEl.hidden = true;
|
startField.endEdit();
|
||||||
editButton.setIcon("lucide-pencil");
|
entry.startTime = startField.getTimestamp();
|
||||||
if (nameBox.getValue()) {
|
endField.endEdit();
|
||||||
entry.name = nameBox.getValue();
|
entry.endTime = endField.getTimestamp();
|
||||||
namePar.setText(entry.name);
|
|
||||||
await saveTracker(tracker, this.app, file, getSectionInfo());
|
await saveTracker(tracker, this.app, file, getSectionInfo());
|
||||||
}
|
editButton.setIcon("lucide-pencil");
|
||||||
} else {
|
} else {
|
||||||
namePar.hidden = true;
|
nameField.beginEdit(entry.name);
|
||||||
nameBox.inputEl.hidden = false;
|
startField.beginEdit((entry.startTime));
|
||||||
nameBox.setValue(entry.name);
|
endField.beginEdit((entry.endTime));
|
||||||
editButton.setIcon("lucide-check");
|
editButton.setIcon("lucide-check");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
.simple-time-tracker-container {
|
||||||
|
overflow-x: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
.simple-time-tracker-support {
|
.simple-time-tracker-support {
|
||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
|
@ -62,3 +66,8 @@
|
||||||
.simple-time-tracker-table .clickable-icon {
|
.simple-time-tracker-table .clickable-icon {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.simple-time-tracker-input {
|
||||||
|
max-width: 150px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
|
@ -25,5 +25,6 @@
|
||||||
"publish": false,
|
"publish": false,
|
||||||
"sync": false,
|
"sync": false,
|
||||||
"canvas": true,
|
"canvas": true,
|
||||||
"bookmarks": true
|
"bookmarks": true,
|
||||||
|
"properties": false
|
||||||
}
|
}
|
|
@ -2,5 +2,5 @@
|
||||||
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.
|
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
|
```simple-time-tracker
|
||||||
{"entries":[{"name":"Segment 1","startTime":1666189948,"endTime":1666189951,"subEntries":null},{"name":"Segment 2","startTime":1666189953,"endTime":1666189961,"subEntries":null},{"name":"Segment 3","startTime":null,"endTime":null,"subEntries":[{"name":"Part 1","startTime":1666189962,"endTime":1666189995,"subEntries":null},{"name":"Part 2","startTime":1666190004,"endTime":1666190025,"subEntries":null},{"name":"Part 3","startTime":1666190094,"endTime":1666190101,"subEntries":null}]},{"name":"Segment 4","startTime":1666190088,"endTime":1666190091,"subEntries":null},{"name":"Segment 5","startTime":1684857704,"endTime":1684857708,"subEntries":null},{"name":"Segment 6","startTime":1684857710,"endTime":1684857712,"subEntries":null},{"name":"Segment 7","startTime":1684857729,"endTime":1684857732,"subEntries":null},{"name":"Segment 8","startTime":1684857743,"endTime":1684857748,"subEntries":null}]}
|
{"entries":[{"name":"Segment 1","startTime":"2022-10-19T14:32:28.000Z","endTime":"2022-10-19T14:32:31.000Z","subEntries":null},{"name":"Segment 2","startTime":"2022-10-19T14:32:33.000Z","endTime":"2022-10-19T14:32:41.000Z","subEntries":null},{"name":"Segment 3","startTime":"1970-01-01T00:00:00.000Z","endTime":null,"subEntries":[{"name":"Part 1","startTime":"2022-10-19T14:32:42.000Z","endTime":"2022-10-19T14:33:15.000Z","subEntries":null},{"name":"Part 2","startTime":"2022-10-19T14:33:24.000Z","endTime":"2022-10-19T14:33:45.000Z","subEntries":null},{"name":"Part 3","startTime":"2022-10-19T14:34:54.000Z","endTime":"2022-10-19T14:35:01.000Z","subEntries":null}]},{"name":"Segment 4","startTime":"2022-10-19T14:34:48.000Z","endTime":"2022-10-19T14:34:51.000Z","subEntries":null},{"name":"Segment 5","startTime":"2023-05-23T16:01:44.000Z","endTime":"2023-05-23T16:01:48.000Z","subEntries":null},{"name":"Segment 6","startTime":"2023-05-23T16:01:50.000Z","endTime":"2023-05-23T16:01:52.000Z","subEntries":null},{"name":"Segment 7","startTime":"2023-05-23T16:02:09.000Z","endTime":"2023-05-23T16:02:12.000Z","subEntries":null},{"name":"Segment 8","startTime":"1970-01-01T00:00:00.000Z","endTime":null,"subEntries":[{"name":"Part 1","startTime":"2023-05-23T16:02:20.000Z","endTime":"2023-05-23T16:02:28.000Z","subEntries":null},{"name":"Part 2","startTime":"2023-09-08T11:58:11.000Z","endTime":"2023-09-08T11:58:38.000Z","subEntries":null}]},{"name":"Segment 9","startTime":"2023-09-08T12:00:35.000Z","endTime":"2023-09-08T12:00:49.991Z","subEntries":null},{"name":"Segment 10","startTime":"2023-09-08T12:01:45.000Z","endTime":"2023-09-08T12:01:53.711Z","subEntries":null}]}
|
||||||
```
|
```
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
"0.1.4": "0.15.0",
|
"0.1.4": "0.15.0",
|
||||||
"0.1.5": "0.15.0",
|
"0.1.5": "0.15.0",
|
||||||
"0.1.6": "0.15.0",
|
"0.1.6": "0.15.0",
|
||||||
"0.1.7": "1.2.8"
|
"0.1.7": "1.2.8",
|
||||||
|
"0.1.8": "1.3.0"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue