From c25e75f8397e8a9c432219ccba9a1c58f72fc656 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Wed, 3 Jun 2026 09:56:17 +0800 Subject: [PATCH] Step 16.1: global worklog dashboard + conservative suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix date timezone: worklog.Add uses local date (was UTC) - Conservative suggestion estimator: - burst detection (10min window), time spread analysis - 5-30 min range, 60+ only with strong evidence - confidence levels: low/medium/high with reason - worklog/report.go: ReportFilter, ListReport, Summary, ExportCSV, ExportMarkdown - Expanded WorklogDTO: date, details, approximate, billable, nodeTitle - New bindings: CreateWorklogFull, ListWorklogReport, WorklogSummary, Export* - New system section 'Журнал' in sidebar with badge (suggestion count) - Global journal screen: filters (date range, includeChildren), table, summary - Suggestions shown on Today dashboard + Journal screen + per-node worklog tab - Suggestion cards: editable minutes, confidence display, apply/open buttons - i18n: all new keys in ru + en --- cmd/verstak-gui/app.go | 15 +- cmd/verstak-gui/bindings_activity.go | 1 + cmd/verstak-gui/bindings_suggest.go | 224 +++++++--- cmd/verstak-gui/bindings_worklog.go | 112 +++-- .../frontend-dist/assets/main-B4G76NhT.css | 1 + .../frontend-dist/assets/main-wlKdkTmp.js | 3 + cmd/verstak-gui/frontend-dist/index.html | 4 +- docs/PLAN.md | 28 +- frontend/src/App.svelte | 282 ++++++++++++- frontend/src/lib/i18n/locales/en.js | 29 ++ frontend/src/lib/i18n/locales/ru.js | 28 ++ internal/core/activity/suggest.go | 23 +- internal/core/worklog/report.go | 398 ++++++++++++++++++ internal/core/worklog/worklog.go | 2 +- 14 files changed, 1030 insertions(+), 120 deletions(-) create mode 100644 cmd/verstak-gui/frontend-dist/assets/main-B4G76NhT.css create mode 100644 cmd/verstak-gui/frontend-dist/assets/main-wlKdkTmp.js create mode 100644 internal/core/worklog/report.go diff --git a/cmd/verstak-gui/app.go b/cmd/verstak-gui/app.go index 49b6feb..1b612b7 100644 --- a/cmd/verstak-gui/app.go +++ b/cmd/verstak-gui/app.go @@ -167,11 +167,16 @@ type ActionDTO struct { } type WorklogDTO struct { - ID string `json:"id"` - NodeID string `json:"nodeId"` - Summary string `json:"summary"` - Minutes int `json:"minutes"` - CreatedAt string `json:"createdAt"` + ID string `json:"id"` + NodeID string `json:"nodeId"` + NodeTitle string `json:"nodeTitle,omitempty"` + Summary string `json:"summary"` + Minutes int `json:"minutes"` + Date string `json:"date,omitempty"` + Details string `json:"details,omitempty"` + Approximate bool `json:"approximate"` + Billable bool `json:"billable"` + CreatedAt string `json:"createdAt"` } type SearchResultDTO struct { diff --git a/cmd/verstak-gui/bindings_activity.go b/cmd/verstak-gui/bindings_activity.go index a2770a9..540e7ae 100644 --- a/cmd/verstak-gui/bindings_activity.go +++ b/cmd/verstak-gui/bindings_activity.go @@ -19,6 +19,7 @@ func (a *App) ListSystemViews() []SystemViewDTO { return []SystemViewDTO{ {ID: "today", Label: i18n.TF("ru", "nav.today")}, {ID: "inbox", Label: i18n.TF("ru", "nav.inbox")}, + {ID: "journal", Label: i18n.TF("ru", "nav.journal")}, {ID: "activity", Label: i18n.TF("ru", "nav.activity")}, } } diff --git a/cmd/verstak-gui/bindings_suggest.go b/cmd/verstak-gui/bindings_suggest.go index f5e3171..48d3f8f 100644 --- a/cmd/verstak-gui/bindings_suggest.go +++ b/cmd/verstak-gui/bindings_suggest.go @@ -4,19 +4,18 @@ import ( "fmt" "sort" "strings" + "time" "verstak/internal/core/activity" + syncsvc "verstak/internal/core/sync" ) -// GetSuggestions analyzes today's activity and returns worklog suggestions. +// GetSuggestions analyzes today's activity and returns conservative suggestions. func (a *App) GetSuggestions() ([]activity.Suggestion, error) { events, err := a.activity.ListTodayEvents() - if err != nil { + if err != nil || len(events) == 0 { return nil, err } - if len(events) == 0 { - return nil, nil - } type acc struct { title string @@ -50,37 +49,27 @@ func (a *App) GetSuggestions() ([]activity.Suggestion, error) { continue } - noteCount := 0 - fileCount := 0 - actionCount := 0 - otherCount := 0 - for _, e := range grp.events { - switch e.EventType { - case activity.TypeNoteCreated, activity.TypeNoteUpdated, activity.TypeNoteDeleted: - noteCount++ - case activity.TypeFileAdded, activity.TypeFileDeleted, activity.TypeFileRenamed, - activity.TypeFileCopied, activity.TypeFileMoved, - activity.TypeFolderAdded, activity.TypeFolderDeleted, activity.TypeFolderRenamed: - fileCount++ - case activity.TypeActionCreated, activity.TypeActionDone: - actionCount++ - default: - otherCount++ - } - } - - summary := buildSuggestionSummary(noteCount, fileCount, actionCount, otherCount) + notes, files, actions, other := countByType(grp.events) + summary := buildSuggestionSummary(notes, files, actions, other) if summary == "" { continue } + spread := timeSpread(grp.events) + bursts := countBursts(grp.events, 10) + min := estimateMinutes(bursts, spread, len(grp.events)) + conf, reason := confidence(bursts, spread, len(grp.events)) + suggestions = append(suggestions, activity.Suggestion{ - NodeID: nodeID, - NodeTitle: grp.title, - Summary: summary, - SuggestedMin: suggestMinutes(noteCount + fileCount + actionCount + otherCount), - EventCount: len(grp.events), - NodeKind: grp.kind, + NodeID: nodeID, + NodeTitle: grp.title, + Summary: summary, + SuggestedMin: min, + EventCount: len(grp.events), + NodeKind: grp.kind, + Confidence: conf, + ConfidenceReason: reason, + TimeSpreadMin: spread, }) } @@ -91,39 +80,160 @@ func (a *App) GetSuggestions() ([]activity.Suggestion, error) { return suggestions, nil } -// AcceptSuggestion creates a worklog entry from a suggestion. +// AcceptSuggestion creates a worklog entry from a suggestion (compatibility wrapper). func (a *App) AcceptSuggestion(s activity.Suggestion) (*WorklogDTO, error) { - return a.CreateWorklog(s.NodeID, s.Summary, s.SuggestedMin) + return a.AcceptSuggestionWith(s, s.SuggestedMin, "") } -func buildSuggestionSummary(noteCount, fileCount, actionCount, otherCount int) string { +// AcceptSuggestionWith creates a worklog entry with optional overrides. +func (a *App) AcceptSuggestionWith(s activity.Suggestion, minutes int, date string) (*WorklogDTO, error) { + d := date + if d == "" { + d = time.Now().Format("2006-01-02") + } + entry, err := a.worklog.AddWithDate(s.NodeID, s.Summary, "", d, minutes, true, false) + if err != nil { + return nil, err + } + _ = a.sync.RecordOp(syncsvc.EntityWorklog, entry.ID, syncsvc.OpCreate, worklogPayload(entry)) + mins := 0 + if entry.Minutes != nil { + mins = *entry.Minutes + } + return &WorklogDTO{ + ID: entry.ID, + NodeID: entry.NodeID, + Summary: entry.Summary, + Minutes: mins, + Date: entry.Date, + CreatedAt: entry.CreatedAt.Format("2006-01-02T15:04:05Z"), + }, nil +} + +// HideSuggestion marks a suggestion as hidden for the session. +// The frontend tracks visibility; this is a no-op on the backend. +func (a *App) HideSuggestion(_ activity.Suggestion) error { + return nil +} + +// --- event analysis --- + +func countByType(events []activity.Event) (notes, files, actions, other int) { + for _, e := range events { + switch e.EventType { + case activity.TypeNoteCreated, activity.TypeNoteUpdated, activity.TypeNoteDeleted: + notes++ + case activity.TypeFileAdded, activity.TypeFileDeleted, activity.TypeFileRenamed, + activity.TypeFileCopied, activity.TypeFileMoved, + activity.TypeFolderAdded, activity.TypeFolderDeleted, activity.TypeFolderRenamed: + files++ + case activity.TypeActionCreated, activity.TypeActionDone: + actions++ + default: + other++ + } + } + return +} + +// timeSpread returns minutes between first and last event. +func timeSpread(events []activity.Event) int { + if len(events) < 2 { + return 0 + } + minTime := events[0].CreatedAt + maxTime := events[0].CreatedAt + for _, e := range events { + if e.CreatedAt < minTime { + minTime = e.CreatedAt + } + if e.CreatedAt > maxTime { + maxTime = e.CreatedAt + } + } + t1, err1 := time.Parse(time.RFC3339, minTime) + t2, err2 := time.Parse(time.RFC3339, maxTime) + if err1 != nil || err2 != nil { + return 0 + } + diff := t2.Sub(t1) + return int(diff.Minutes()) +} + +// countBursts groups events into bursts where consecutive events +// are within `windowMin` minutes of each other. +func countBursts(events []activity.Event, windowMin int) int { + if len(events) == 0 { + return 0 + } + + times := make([]time.Time, 0, len(events)) + for _, e := range events { + t, err := time.Parse(time.RFC3339, e.CreatedAt) + if err != nil { + continue + } + times = append(times, t) + } + if len(times) == 0 { + return 1 + } + sort.Slice(times, func(i, j int) bool { return times[i].Before(times[j]) }) + + bursts := 1 + last := times[0] + for _, t := range times[1:] { + if t.Sub(last) > time.Duration(windowMin)*time.Minute { + bursts++ + } + last = t + } + return bursts +} + +// estimateMinutes conservatively estimates suggested minutes. +func estimateMinutes(bursts, spread, totalEvents int) int { + if totalEvents <= 1 { + return 5 + } + switch { + case spread >= 60 && bursts >= 3 && totalEvents >= 8: + return 30 + case spread >= 30 && bursts >= 2 && totalEvents >= 5: + return 20 + case spread >= 15 && bursts >= 2 && totalEvents >= 3: + return 15 + case totalEvents >= 3: + return 10 + default: + return 5 + } +} + +// confidence returns a label and reason string for the estimate. +func confidence(bursts, spread, totalEvents int) (string, string) { + if spread >= 60 && totalEvents >= 10 { + return activity.ConfidenceHigh, fmt.Sprintf("активность растянута на %d минут, %d всплесков", spread, bursts) + } + if spread >= 30 && totalEvents >= 5 && bursts >= 2 { + return activity.ConfidenceMedium, fmt.Sprintf("несколько всплесков активности за %d минут", spread) + } + return activity.ConfidenceLow, fmt.Sprintf("%d событий за %d минут, %d всплесков", totalEvents, spread, bursts) +} + +func buildSuggestionSummary(notes, files, actions, other int) string { var parts []string - if noteCount > 0 { - parts = append(parts, fmt.Sprintf("заметки (%d)", noteCount)) + if notes > 0 { + parts = append(parts, fmt.Sprintf("заметки (%d)", notes)) } - if fileCount > 0 { - parts = append(parts, fmt.Sprintf("файлы (%d)", fileCount)) + if files > 0 { + parts = append(parts, fmt.Sprintf("файлы (%d)", files)) } - if actionCount > 0 { - parts = append(parts, fmt.Sprintf("действия (%d)", actionCount)) + if actions > 0 { + parts = append(parts, fmt.Sprintf("действия (%d)", actions)) } - if otherCount > 0 { - parts = append(parts, fmt.Sprintf("события (%d)", otherCount)) + if other > 0 { + parts = append(parts, fmt.Sprintf("события (%d)", other)) } return strings.Join(parts, ", ") } - -func suggestMinutes(totalEvents int) int { - switch { - case totalEvents >= 15: - return 120 - case totalEvents >= 10: - return 90 - case totalEvents >= 6: - return 60 - case totalEvents >= 3: - return 30 - default: - return 15 - } -} diff --git a/cmd/verstak-gui/bindings_worklog.go b/cmd/verstak-gui/bindings_worklog.go index 91173ad..b2a3e8c 100644 --- a/cmd/verstak-gui/bindings_worklog.go +++ b/cmd/verstak-gui/bindings_worklog.go @@ -2,6 +2,7 @@ package main import ( syncsvc "verstak/internal/core/sync" + "verstak/internal/core/worklog" ) func (a *App) ListWorklog(nodeID string) ([]WorklogDTO, error) { @@ -9,38 +10,101 @@ func (a *App) ListWorklog(nodeID string) ([]WorklogDTO, error) { if err != nil { return nil, err } - result := make([]WorklogDTO, len(list)) - for i := range list { - mins := 0 - if list[i].Minutes != nil { - mins = *list[i].Minutes - } - result[i] = WorklogDTO{ - ID: list[i].ID, - NodeID: list[i].NodeID, - Summary: list[i].Summary, - Minutes: mins, - CreatedAt: list[i].CreatedAt.Format("2006-01-02T15:04:05Z"), - } - } - return result, nil + return toWorklogDTOs(list), nil } func (a *App) CreateWorklog(nodeID, summary string, minutes int) (*WorklogDTO, error) { - entry, err := a.worklog.Add(nodeID, summary, "", minutes, false, false) + return a.CreateWorklogFull(nodeID, summary, "", "", minutes, false, false) +} + +func (a *App) CreateWorklogFull(nodeID, summary, details, date string, minutes int, approximate, billable bool) (*WorklogDTO, error) { + if date == "" { + entry, err := a.worklog.Add(nodeID, summary, details, minutes, approximate, billable) + if err != nil { + return nil, err + } + _ = a.sync.RecordOp(syncsvc.EntityWorklog, entry.ID, syncsvc.OpCreate, worklogPayload(entry)) + return entryToDTO(entry), nil + } + entry, err := a.worklog.AddWithDate(nodeID, summary, details, date, minutes, approximate, billable) if err != nil { return nil, err } _ = a.sync.RecordOp(syncsvc.EntityWorklog, entry.ID, syncsvc.OpCreate, worklogPayload(entry)) + return entryToDTO(entry), nil +} + +// --- report bindings --- + +func (a *App) ListWorklogReport(dateFrom, dateTo, nodeID string, includeChildren bool) ([]worklog.ReportRow, error) { + f := worklog.ReportFilter{ + DateFrom: dateFrom, + DateTo: dateTo, + NodeID: nodeID, + IncludeChildren: includeChildren, + } + rows, err := a.worklog.ListReport(f) + if err != nil { + return nil, err + } + a.worklog.BuildReportPaths(rows) + return rows, nil +} + +func (a *App) WorklogReportSummary(dateFrom, dateTo, nodeID string, includeChildren bool) (*worklog.ReportSummary, error) { + f := worklog.ReportFilter{ + DateFrom: dateFrom, + DateTo: dateTo, + NodeID: nodeID, + IncludeChildren: includeChildren, + } + return a.worklog.Summary(f) +} + +func (a *App) ExportWorklogCSV(dateFrom, dateTo, nodeID string, includeChildren bool) (string, error) { + f := worklog.ReportFilter{ + DateFrom: dateFrom, + DateTo: dateTo, + NodeID: nodeID, + IncludeChildren: includeChildren, + } + return a.worklog.ExportCSV(f) +} + +func (a *App) ExportWorklogMarkdown(dateFrom, dateTo, nodeID string, includeChildren bool) (string, error) { + f := worklog.ReportFilter{ + DateFrom: dateFrom, + DateTo: dateTo, + NodeID: nodeID, + IncludeChildren: includeChildren, + } + return a.worklog.ExportMarkdown(f) +} + +// --- helpers --- + +func toWorklogDTOs(list []worklog.Entry) []WorklogDTO { + result := make([]WorklogDTO, len(list)) + for i := range list { + result[i] = *entryToDTO(&list[i]) + } + return result +} + +func entryToDTO(e *worklog.Entry) *WorklogDTO { mins := 0 - if entry.Minutes != nil { - mins = *entry.Minutes + if e.Minutes != nil { + mins = *e.Minutes } return &WorklogDTO{ - ID: entry.ID, - NodeID: entry.NodeID, - Summary: entry.Summary, - Minutes: mins, - CreatedAt: entry.CreatedAt.Format("2006-01-02T15:04:05Z"), - }, nil + ID: e.ID, + NodeID: e.NodeID, + Summary: e.Summary, + Minutes: mins, + Date: e.Date, + Details: e.Details, + Approximate: e.Approximate, + Billable: e.Billable, + CreatedAt: e.CreatedAt.Format("2006-01-02T15:04:05Z"), + } } diff --git a/cmd/verstak-gui/frontend-dist/assets/main-B4G76NhT.css b/cmd/verstak-gui/frontend-dist/assets/main-B4G76NhT.css new file mode 100644 index 0000000..308dabc --- /dev/null +++ b/cmd/verstak-gui/frontend-dist/assets/main-B4G76NhT.css @@ -0,0 +1 @@ +.file-row.svelte-1skuef2.svelte-1skuef2{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:6px;cursor:default;transition:background .12s;min-height:52px;-webkit-user-select:none;user-select:none;position:relative}.file-row.svelte-1skuef2.svelte-1skuef2:hover{background:#1e1e30}.file-row--selected.svelte-1skuef2.svelte-1skuef2{background:#1e1e3a;outline:1px solid #3a3a6c}.file-row--selected.svelte-1skuef2.svelte-1skuef2:hover{background:#252545}.file-row.svelte-1skuef2.svelte-1skuef2:focus-visible{outline:2px solid #5588ff;outline-offset:-2px}.file-row-icon.svelte-1skuef2.svelte-1skuef2{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:32px;height:32px;color:#888}.file-row-body.svelte-1skuef2.svelte-1skuef2{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.file-row-name.svelte-1skuef2.svelte-1skuef2{font-size:13px;color:#ddd;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}.file-row-meta.svelte-1skuef2.svelte-1skuef2{display:flex;align-items:center;gap:4px;font-size:11px;color:#666}.meta-sep.svelte-1skuef2.svelte-1skuef2{color:#444}.file-row-actions.svelte-1skuef2.svelte-1skuef2{display:flex;gap:2px;align-items:center;opacity:0;transition:opacity .15s ease;flex-shrink:0}.file-row.svelte-1skuef2:hover .file-row-actions.svelte-1skuef2{opacity:1}.action-btn.svelte-1skuef2.svelte-1skuef2{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;border-radius:4px;background:transparent;color:#666;cursor:pointer;transition:background .12s,color .12s}.action-btn.svelte-1skuef2.svelte-1skuef2:hover{background:#2a2a3c;color:#ccc}.action-btn-danger.svelte-1skuef2.svelte-1skuef2:hover{background:#3a2222;color:#ff6b6b}.action-btn.svelte-1skuef2.svelte-1skuef2:focus-visible{outline:2px solid #5588ff;outline-offset:1px}.menu-backdrop.svelte-1skuef2.svelte-1skuef2{position:fixed;top:0;right:0;bottom:0;left:0;z-index:99}.menu.svelte-1skuef2.svelte-1skuef2{position:fixed;background:#1a1a28;border:1px solid #2a2a3c;border-radius:8px;padding:4px;z-index:100;min-width:220px;box-shadow:0 4px 16px #00000080}.menu-item.svelte-1skuef2.svelte-1skuef2{display:flex;align-items:center;gap:8px;width:100%;padding:7px 10px;border:none;background:transparent;color:#ccc;font-size:12px;text-align:left;cursor:pointer;border-radius:4px;font-family:inherit}.menu-item.svelte-1skuef2.svelte-1skuef2:hover{background:#2a2a3c;color:#fff}.menu-item-danger.svelte-1skuef2.svelte-1skuef2{color:#ff6b6b}.menu-item-danger.svelte-1skuef2.svelte-1skuef2:hover{background:#3a2222}.menu-item.svelte-1skuef2.svelte-1skuef2:focus-visible{outline:2px solid #5588ff;outline-offset:1px}.menu-sep.svelte-1skuef2.svelte-1skuef2{height:1px;background:#2a2a3c;margin:4px 8px}.breadcrumbs.svelte-csi2lb{display:flex;align-items:center;gap:4px;padding:8px 0;font-size:13px;color:#999}.sep.svelte-csi2lb{color:#444}.crumb.svelte-csi2lb{font-size:13px}.crumb--current.svelte-csi2lb{color:#ccc}.crumb--link.svelte-csi2lb{background:none;border:none;padding:2px 4px;color:#888;cursor:pointer;border-radius:3px;font-family:inherit;font-size:13px;transition:color .12s,background .12s}.crumb--link.svelte-csi2lb:hover{color:#ccc;background:#1e1e30}.crumb--link.svelte-csi2lb:focus-visible{outline:2px solid #5588ff;outline-offset:1px}.overlay.svelte-1cw3u0m{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000a6;display:flex;align-items:center;justify-content:center;z-index:1000}.modal.svelte-1cw3u0m{background:#14141f;border:1px solid #2a2a3c;border-radius:10px;width:90vw;max-width:900px;height:85vh;max-height:700px;display:flex;flex-direction:column;overflow:hidden}.preview-header.svelte-1cw3u0m{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid #2a2a3c;flex-shrink:0}.preview-title.svelte-1cw3u0m{display:flex;align-items:center;gap:8px;color:#ddd;font-size:14px;min-width:0}.preview-name.svelte-1cw3u0m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-meta.svelte-1cw3u0m{font-size:11px;color:#666;margin-left:auto;white-space:nowrap}.preview-actions.svelte-1cw3u0m{display:flex;gap:4px;flex-shrink:0;margin-left:8px}.action-btn.svelte-1cw3u0m{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;border-radius:4px;background:transparent;color:#666;cursor:pointer;transition:background .12s,color .12s}.action-btn.svelte-1cw3u0m:hover{background:#2a2a3c;color:#ccc}.action-btn.svelte-1cw3u0m:focus-visible{outline:2px solid #5588ff;outline-offset:1px}.action-btn-close.svelte-1cw3u0m{color:#ff6b6b}.action-btn-close.svelte-1cw3u0m:hover{background:#3a2222;color:#f44}.preview-body.svelte-1cw3u0m{flex:1;overflow:auto;min-height:0}.preview-status.svelte-1cw3u0m{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:48px 24px;color:#888;font-size:14px}.preview-image-container.svelte-1cw3u0m{display:flex;align-items:center;justify-content:center;padding:16px;min-height:200px;background:#0e0e18}.preview-image.svelte-1cw3u0m{max-width:100%;max-height:calc(85vh - 100px);object-fit:contain;border-radius:4px}.preview-text.svelte-1cw3u0m{margin:0;padding:16px;font-family:SF Mono,Fira Code,Cascadia Code,Consolas,monospace;font-size:12px;line-height:1.5;color:#ccc;white-space:pre-wrap;word-wrap:break-word;overflow:auto}.preview-pdf-container.svelte-1cw3u0m{width:100%;height:100%}.preview-pdf.svelte-1cw3u0m{width:100%;height:100%;border:none}.btn-sm.svelte-1cw3u0m{padding:6px 14px;border:1px solid #2a2a3c;background:#1a1a28;color:#ccc;border-radius:6px;cursor:pointer;font-size:12px;font-family:inherit;transition:background .12s}.btn-sm.svelte-1cw3u0m:hover{background:#223}.overlay.svelte-1fv6yyk{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:200}.modal.svelte-1fv6yyk{background:#1a1a28;border:1px solid #2a2a3c;border-radius:12px;padding:24px;width:360px;max-width:90vw}h3.svelte-1fv6yyk{font-size:18px;margin-bottom:12px;color:#e4e4ef}.message.svelte-1fv6yyk{font-size:14px;color:#aaa;margin-bottom:20px;line-height:1.4}.actions.svelte-1fv6yyk{display:flex;gap:8px;justify-content:flex-end}.btn.svelte-1fv6yyk{padding:8px 16px;border:1px solid #2a2a3c;background:#1a1a28;color:#ccc;border-radius:6px;cursor:pointer;font-size:13px;font-family:inherit}.btn.svelte-1fv6yyk:hover{background:#223}.btn-primary.svelte-1fv6yyk{background:#6366f1;border-color:#6366f1;color:#fff}.btn-primary.svelte-1fv6yyk:hover{background:#4f46e5}.btn-danger.svelte-1fv6yyk{background:#dc2626;border-color:#dc2626;color:#fff}.btn-danger.svelte-1fv6yyk:hover{background:#b91c1c}.btn.svelte-1fv6yyk:focus-visible{outline:2px solid #5588ff;outline-offset:1px}.tree-item.svelte-zj71cl.svelte-zj71cl{display:flex;align-items:center;height:32px;padding-right:8px;cursor:default;font-size:13px;color:#ccc;-webkit-user-select:none;user-select:none}.tree-item.svelte-zj71cl.svelte-zj71cl:hover{background:#223}.tree-item.selected.svelte-zj71cl.svelte-zj71cl{background:#2a2a4a;color:#fff;font-weight:500}.tree-item.drop-valid.svelte-zj71cl.svelte-zj71cl{background:#1a3a1a;outline:1px solid #4ade80;outline-offset:-1px}.tree-item.drop-invalid.svelte-zj71cl.svelte-zj71cl{background:#3a1a1a;outline:1px solid #ff6b6b;outline-offset:-1px}.tree-toggle.svelte-zj71cl.svelte-zj71cl{background:none;border:none;color:#666;cursor:pointer;padding:0;width:20px;height:32px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;font-family:inherit;line-height:1;font-size:12px}.tree-toggle.svelte-zj71cl.svelte-zj71cl:hover{color:#a5b4fc}.tree-toggle-placeholder.svelte-zj71cl.svelte-zj71cl{display:inline-block;width:20px;flex-shrink:0}.tree-icon.svelte-zj71cl.svelte-zj71cl{display:inline-flex;align-items:center;justify-content:center;width:20px;height:32px;flex-shrink:0;color:#888;margin-right:4px;cursor:pointer}.tree-icon.svelte-zj71cl.svelte-zj71cl:hover,.tree-item.selected.svelte-zj71cl .tree-icon.svelte-zj71cl{color:#a5b4fc}.tree-label.svelte-zj71cl.svelte-zj71cl{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;line-height:32px}.svelte-44iz1r.svelte-44iz1r,.svelte-44iz1r.svelte-44iz1r:before,.svelte-44iz1r.svelte-44iz1r:after{box-sizing:border-box;margin:0;padding:0}.app.svelte-44iz1r.svelte-44iz1r{display:flex;width:100vw;height:100vh;overflow:hidden;background:#13131f;color:#e4e4ef;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px}.sidebar.svelte-44iz1r.svelte-44iz1r{width:260px;min-width:200px;height:100vh;display:flex;flex-direction:column;background:#1a1a28;border-right:1px solid #2a2a3c;flex-shrink:0;overflow:hidden}.sidebar-brand.svelte-44iz1r.svelte-44iz1r{padding:16px 20px;display:flex;align-items:center;gap:10px;border-bottom:1px solid #2a2a3c;flex-shrink:0}.logo.svelte-44iz1r.svelte-44iz1r{font-size:20px;line-height:1}.brand-name.svelte-44iz1r.svelte-44iz1r{font-size:16px;font-weight:600}.sidebar-nav.svelte-44iz1r.svelte-44iz1r{flex:1;overflow-y:auto;padding:12px 0}.nav-group.svelte-44iz1r.svelte-44iz1r{margin-bottom:16px}.nav-label.svelte-44iz1r.svelte-44iz1r{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:#666;padding:4px 20px;margin-bottom:4px}.nav-item.svelte-44iz1r.svelte-44iz1r{display:block;width:100%;padding:8px 20px;border:none;background:none;color:#ccc;font-size:13px;text-align:left;cursor:pointer;border-radius:0;font-family:inherit}.nav-item.svelte-44iz1r.svelte-44iz1r:hover{background:#223}.nav-item.selected.svelte-44iz1r.svelte-44iz1r{background:#2a2a4a;color:#fff;font-weight:500}.workspace-tree-area.svelte-44iz1r.svelte-44iz1r{min-height:32px}.workspace-tree-area.drop-valid.svelte-44iz1r.svelte-44iz1r{outline:2px dashed #4ade80;outline-offset:-2px;background:#4ade800d}.nav-empty.svelte-44iz1r.svelte-44iz1r{padding:8px 20px;color:#555;font-size:12px}.nav-label-row.svelte-44iz1r.svelte-44iz1r{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:#666;padding:4px 20px;margin-bottom:4px;display:flex;align-items:center;justify-content:space-between}.nav-add-btn.svelte-44iz1r.svelte-44iz1r{background:none;border:none;color:#666;cursor:pointer;font-size:16px;padding:0 4px;font-family:inherit;line-height:1}.nav-add-btn.svelte-44iz1r.svelte-44iz1r:hover{color:#ccc}.context-menu-backdrop.svelte-44iz1r.svelte-44iz1r{position:fixed;top:0;right:0;bottom:0;left:0;z-index:200}.context-menu.svelte-44iz1r.svelte-44iz1r{position:fixed;background:#1a1a28;border:1px solid #2a2a3c;border-radius:8px;padding:4px;min-width:180px;box-shadow:0 8px 24px #0006}.context-menu-section.svelte-44iz1r.svelte-44iz1r{padding:6px 12px;font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:#666}.context-menu-item.svelte-44iz1r.svelte-44iz1r{display:flex;width:100%;padding:6px 12px;border:none;background:none;color:#ccc;font-size:13px;text-align:left;cursor:pointer;border-radius:4px;font-family:inherit;align-items:center;gap:6px}.context-menu-item.svelte-44iz1r.svelte-44iz1r:hover{background:#223;color:#fff}.context-menu-item.danger.svelte-44iz1r.svelte-44iz1r{color:#ff6b6b}.context-menu-item.danger.svelte-44iz1r.svelte-44iz1r:hover{background:#3a2222;color:#ff6b6b}.context-menu-divider.svelte-44iz1r.svelte-44iz1r{height:1px;background:#2a2a3c;margin:4px 0}.create-context.svelte-44iz1r.svelte-44iz1r{font-size:12px;color:#888;margin-bottom:12px}.sidebar-footer.svelte-44iz1r.svelte-44iz1r{padding:8px 12px;border-top:1px solid #2a2a3c;flex-shrink:0;display:flex;flex-direction:column;gap:4px}.version.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;text-align:center}.main.svelte-44iz1r.svelte-44iz1r{flex:1;display:flex;flex-direction:column;height:100vh;min-width:0;overflow:hidden;background:#13131f}.header.svelte-44iz1r.svelte-44iz1r{padding:12px 24px;border-bottom:1px solid #2a2a3c;display:flex;align-items:center;flex-shrink:0;min-height:48px}.header-left.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px;flex:1}.header-right.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px}.header-sync-btn.svelte-44iz1r.svelte-44iz1r{background:#1e1e38;border:1px solid #6366f1;border-radius:8px;padding:6px 12px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;color:#c0c0f0;font-family:inherit;font-size:13px;position:relative}.header-sync-btn.svelte-44iz1r.svelte-44iz1r:hover{background:#2a2a50;color:#e4e4ef;border-color:#818cf8}.header-sync-btn.svelte-44iz1r.svelte-44iz1r:disabled{opacity:.5;cursor:not-allowed}.sync-badge.svelte-44iz1r.svelte-44iz1r{background:#6366f1;color:#fff;font-size:10px;border-radius:50%;width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center;position:absolute;top:-6px;right:-6px}.crumb.svelte-44iz1r.svelte-44iz1r{font-size:14px;font-weight:500}.crumb.placeholder.svelte-44iz1r.svelte-44iz1r{color:#666}.crumb-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;background:#1e1e2e;padding:2px 8px;border-radius:10px;margin-left:8px}.error-banner.svelte-44iz1r.svelte-44iz1r{background:#3a2222;color:#f88;padding:8px 24px;font-size:12px;border-bottom:1px solid #4a2222;flex-shrink:0;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.dismiss-btn.svelte-44iz1r.svelte-44iz1r{background:none;border:none;color:#f66;cursor:pointer;padding:2px;display:flex;align-items:center;border-radius:2px}.dismiss-btn.svelte-44iz1r.svelte-44iz1r:hover{color:#f44}.tabs.svelte-44iz1r.svelte-44iz1r{display:flex;border-bottom:1px solid #2a2a3c;flex-shrink:0;padding:0 24px}.tab.svelte-44iz1r.svelte-44iz1r{padding:10px 16px;border:none;background:none;color:#888;font-size:13px;cursor:pointer;border-bottom:2px solid transparent;font-family:inherit}.tab.svelte-44iz1r.svelte-44iz1r:hover{color:#a5b4fc}.tab.active.svelte-44iz1r.svelte-44iz1r{color:#e4e4ef;border-bottom-color:#818cf8;background:#6366f11f;font-weight:600}.tab-content.svelte-44iz1r.svelte-44iz1r{flex:1;overflow-y:auto}.note-editor.svelte-44iz1r.svelte-44iz1r{flex:1;display:flex;flex-direction:column;height:100%}.note-editor-header.svelte-44iz1r.svelte-44iz1r{padding:12px 24px;border-bottom:1px solid #2a2a3c;display:flex;align-items:center;gap:12px;flex-shrink:0}.note-title.svelte-44iz1r.svelte-44iz1r{font-size:16px;font-weight:500}.dirty-mark.svelte-44iz1r.svelte-44iz1r{color:#f59e0b;font-size:10px}.note-editor-actions.svelte-44iz1r.svelte-44iz1r{margin-left:auto;display:flex;gap:8px}.note-textarea.svelte-44iz1r.svelte-44iz1r{flex:1;width:100%;border:none;outline:none;background:#13131f;color:#e4e4ef;font-family:SF Mono,Fira Code,monospace;font-size:14px;line-height:1.6;padding:24px;resize:none}.overview.svelte-44iz1r.svelte-44iz1r{padding:24px}.overview.svelte-44iz1r h2.svelte-44iz1r{font-size:24px;margin-bottom:16px}.meta-grid.svelte-44iz1r.svelte-44iz1r{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px;margin-bottom:24px}.meta-item.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;padding:12px 16px;border-radius:8px}.meta-label.svelte-44iz1r.svelte-44iz1r{display:block;font-size:11px;color:#666;margin-bottom:4px;text-transform:uppercase}.quick-actions.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;margin-bottom:24px;flex-wrap:wrap}.qa-btn.svelte-44iz1r.svelte-44iz1r{padding:10px 16px;border:1px solid #2a2a3c;background:#1a1a28;color:#ccc;border-radius:8px;cursor:pointer;font-size:13px;font-family:inherit;display:inline-flex;align-items:center;gap:6px}.qa-btn.svelte-44iz1r.svelte-44iz1r:hover{background:#223}.qa-btn.svelte-44iz1r.svelte-44iz1r:disabled{opacity:.4;cursor:not-allowed}.recent-section.svelte-44iz1r.svelte-44iz1r{margin-bottom:24px}.recent-section.svelte-44iz1r h3.svelte-44iz1r{font-size:13px;color:#666;text-transform:uppercase;margin-bottom:8px}.recent-note.svelte-44iz1r.svelte-44iz1r{padding:8px 12px;border-radius:6px;cursor:pointer;display:flex;justify-content:space-between}.recent-note.svelte-44iz1r.svelte-44iz1r:hover{background:#1a1a28}.recent-date.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555}.recent-entry.svelte-44iz1r.svelte-44iz1r{padding:6px 0;font-size:13px;color:#888;border-bottom:1px solid #1a1a28}.notes-tab.svelte-44iz1r.svelte-44iz1r{padding:24px}.tab-toolbar.svelte-44iz1r.svelte-44iz1r{margin-bottom:16px}.create-form.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;padding:16px;border-radius:8px;margin-bottom:16px}.create-form.svelte-44iz1r input.svelte-44iz1r{width:100%;padding:8px 12px;border:1px solid #2a2a3c;background:#13131f;color:#e4e4ef;border-radius:4px;font-size:14px;font-family:inherit;margin-bottom:8px}.create-form.svelte-44iz1r input.svelte-44iz1r:focus{outline:none;border-color:#6366f1}.form-actions.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px}.notes-list.svelte-44iz1r.svelte-44iz1r{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}.note-card.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;border:1px solid #2a2a3c;border-radius:8px;padding:16px;cursor:pointer}.note-card.svelte-44iz1r.svelte-44iz1r:hover{border-color:#3a3a5c}.note-card-title.svelte-44iz1r.svelte-44iz1r{font-size:14px;font-weight:500;margin-bottom:4px}.note-card-date.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555}.worklog-tab.svelte-44iz1r.svelte-44iz1r{padding:24px}.worklog-form.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;margin-bottom:24px;align-items:center}.worklog-form.svelte-44iz1r input.svelte-44iz1r{padding:8px 12px;border:1px solid #2a2a3c;background:#13131f;color:#e4e4ef;border-radius:4px;font-size:14px;font-family:inherit}.worklog-form.svelte-44iz1r input.svelte-44iz1r:focus{outline:none;border-color:#6366f1}.worklog-form.svelte-44iz1r input[type=text].svelte-44iz1r{flex:1}.worklog-form.svelte-44iz1r input[type=number].svelte-44iz1r{width:70px}.worklog-entry.svelte-44iz1r.svelte-44iz1r{padding:12px 0;border-bottom:1px solid #1a1a28}.suggestions-title.svelte-44iz1r.svelte-44iz1r{font-size:13px;font-weight:600;color:#a5b4fc;margin-bottom:12px;text-transform:uppercase;letter-spacing:.5px}.suggestion-summary.svelte-44iz1r.svelte-44iz1r{font-size:14px;color:#e4e4ef}.suggestion-meta.svelte-44iz1r.svelte-44iz1r{font-size:12px;color:#8888a0;margin-top:2px}.suggestion-card.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:#1e1e32;border-radius:6px;margin-bottom:8px;gap:12px}.suggestion-card.svelte-44iz1r.svelte-44iz1r:last-child{margin-bottom:0}.suggestion-info.svelte-44iz1r.svelte-44iz1r{flex:1;display:flex;flex-direction:column;gap:2px}.suggestion-node.svelte-44iz1r.svelte-44iz1r{color:#a5b4fc;font-weight:600;font-size:13px;text-decoration:none;cursor:pointer}.suggestion-node.svelte-44iz1r.svelte-44iz1r:hover{text-decoration:underline}.suggestion-actions.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:6px;flex-shrink:0}.suggestion-min-input.svelte-44iz1r.svelte-44iz1r{width:60px;padding:4px 8px;border:1px solid #2a2a3c;background:#13131f;color:#e4e4ef;border-radius:4px;font-size:14px;text-align:center}.suggestion-min-label.svelte-44iz1r.svelte-44iz1r{font-size:12px;color:#8888a0}.suggestion-confidence.svelte-44iz1r.svelte-44iz1r{font-size:11px;padding:2px 6px;border-radius:3px}.suggestion-confidence.low.svelte-44iz1r.svelte-44iz1r{color:#fbbf24}.suggestion-confidence.medium.svelte-44iz1r.svelte-44iz1r{color:#60a5fa}.suggestion-confidence.high.svelte-44iz1r.svelte-44iz1r{color:#34d399}.journal-screen.svelte-44iz1r.svelte-44iz1r{padding:24px;overflow-y:auto;flex:1}.journal-header.svelte-44iz1r.svelte-44iz1r{margin-bottom:24px}.journal-header.svelte-44iz1r h2.svelte-44iz1r{margin:0 0 16px}.journal-filters.svelte-44iz1r.svelte-44iz1r{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap}.journal-filters.svelte-44iz1r label.svelte-44iz1r{display:flex;flex-direction:column;gap:4px;font-size:12px;color:#8888a0}.journal-filters.svelte-44iz1r input[type=date].svelte-44iz1r{padding:6px 10px;border:1px solid #2a2a3c;background:#13131f;color:#e4e4ef;border-radius:4px;font-size:13px;font-family:inherit}.journal-filters.svelte-44iz1r .checkbox-label.svelte-44iz1r{flex-direction:row;align-items:center;gap:6px;cursor:pointer}.journal-filters.svelte-44iz1r .checkbox-label input.svelte-44iz1r{width:auto}.journal-summary.svelte-44iz1r.svelte-44iz1r{display:flex;flex-wrap:wrap;gap:24px;margin-bottom:24px;padding:16px;background:#1a1a2e;border-radius:8px;border:1px solid #2a2a3c}.summary-total.svelte-44iz1r.svelte-44iz1r{font-size:18px;font-weight:700;color:#e4e4ef;width:100%;margin-bottom:4px}.summary-section.svelte-44iz1r.svelte-44iz1r{flex:1;min-width:200px}.summary-label.svelte-44iz1r.svelte-44iz1r{font-size:12px;font-weight:600;color:#a5b4fc;text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px}.summary-row.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;font-size:13px;padding:4px 0;border-bottom:1px solid #2a2a3c}.summary-row.svelte-44iz1r span.svelte-44iz1r:first-child{flex:1;color:#e4e4ef}.summary-count.svelte-44iz1r.svelte-44iz1r{color:#8888a0}.journal-table-wrap.svelte-44iz1r.svelte-44iz1r{overflow-x:auto}.journal-table.svelte-44iz1r.svelte-44iz1r{width:100%;border-collapse:collapse;font-size:13px}.journal-table.svelte-44iz1r th.svelte-44iz1r{text-align:left;padding:8px 12px;border-bottom:2px solid #2a2a3c;color:#8888a0;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px;white-space:nowrap}.journal-table.svelte-44iz1r td.svelte-44iz1r{padding:8px 12px;border-bottom:1px solid #1a1a28;color:#e4e4ef}.journal-table.svelte-44iz1r .link-btn.svelte-44iz1r{color:#a5b4fc}.journal-path-cell.svelte-44iz1r.svelte-44iz1r{max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#8888a0;font-size:12px}.journal-min-cell.svelte-44iz1r.svelte-44iz1r{text-align:right;font-variant-numeric:tabular-nums}.journal-date-cell.svelte-44iz1r.svelte-44iz1r{color:#8888a0;white-space:nowrap}.today-suggestions.svelte-44iz1r.svelte-44iz1r{margin-bottom:24px}.link-btn.svelte-44iz1r.svelte-44iz1r{background:none;border:none;padding:0;color:#a5b4fc;font:inherit;cursor:pointer;text-align:left}.link-btn.svelte-44iz1r.svelte-44iz1r:hover{text-decoration:underline}.nav-badge.svelte-44iz1r.svelte-44iz1r{background:#6366f1;color:#fff;font-size:10px;font-weight:700;border-radius:10px;padding:1px 6px;margin-left:6px;line-height:1.4}.wl-meta.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;margin-top:2px}.actions-tab.svelte-44iz1r.svelte-44iz1r{padding:24px}.action-card.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;padding:12px 16px;border-radius:8px;display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:8px}.action-info.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.action-title.svelte-44iz1r.svelte-44iz1r{font-weight:500}.action-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#888;background:#223;padding:2px 8px;border-radius:10px;white-space:nowrap}.action-data.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;font-family:SF Mono,Fira Code,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}.action-btns.svelte-44iz1r.svelte-44iz1r{display:flex;gap:4px;flex-shrink:0}.action-btns.svelte-44iz1r .btn-danger.svelte-44iz1r{color:#ff6b6b;border-color:#4a2222;padding:4px 8px}.action-btns.svelte-44iz1r .btn-danger.svelte-44iz1r:hover{background:#3a2222}.empty-state.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center}.empty-state.svelte-44iz1r p.svelte-44iz1r{margin:0;font-size:14px;color:#666}.empty-state.svelte-44iz1r .empty-icon.svelte-44iz1r{margin-bottom:12px;color:#444}.empty-state.svelte-44iz1r .hint.svelte-44iz1r{font-size:12px;color:#555;margin-top:6px}.empty-state.svelte-44iz1r .empty-actions.svelte-44iz1r{display:flex;gap:8px;justify-content:center;margin-top:16px}.welcome.svelte-44iz1r.svelte-44iz1r{padding:48px 24px;text-align:center}.welcome.svelte-44iz1r h2.svelte-44iz1r{font-size:32px;font-weight:300;color:#8888a4;margin-bottom:16px}.welcome.svelte-44iz1r p.svelte-44iz1r{color:#666;font-size:14px}.error-text.svelte-44iz1r.svelte-44iz1r{color:#f88}.modal-overlay.svelte-44iz1r.svelte-44iz1r{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100}.modal.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;border:1px solid #2a2a3c;border-radius:12px;padding:24px;width:400px;max-width:90vw}.modal.svelte-44iz1r h3.svelte-44iz1r{font-size:18px;margin-bottom:16px}.form-group.svelte-44iz1r.svelte-44iz1r{margin-bottom:12px}.form-group.svelte-44iz1r label.svelte-44iz1r{display:block}.form-group.svelte-44iz1r .label-text.svelte-44iz1r,.form-group.svelte-44iz1r .form-label.svelte-44iz1r{display:block;font-size:12px;color:#666;margin-bottom:4px}.form-group.svelte-44iz1r input.svelte-44iz1r,.form-group.svelte-44iz1r select.svelte-44iz1r{width:100%;padding:8px 12px;border:1px solid #2a2a3c;background:#13131f;color:#e4e4ef;border-radius:4px;font-size:14px;font-family:inherit}.form-group.svelte-44iz1r select.svelte-44iz1r{-moz-appearance:none;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M2 4l4 4 4-4'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:32px}.form-group.svelte-44iz1r input.svelte-44iz1r:focus,.form-group.svelte-44iz1r select.svelte-44iz1r:focus{outline:none;border-color:#6366f1}.modal-actions.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}.btn.svelte-44iz1r.svelte-44iz1r{padding:8px 16px;border:1px solid #2a2a3c;background:#1a1a28;color:#ccc;border-radius:6px;cursor:pointer;font-size:13px;font-family:inherit}.btn.svelte-44iz1r.svelte-44iz1r:hover{background:#223}.btn-primary.svelte-44iz1r.svelte-44iz1r{background:#6366f1;border-color:#6366f1;color:#fff}.btn-primary.svelte-44iz1r.svelte-44iz1r:hover{background:#4f46e5}.btn.svelte-44iz1r.svelte-44iz1r:disabled{opacity:.4;cursor:not-allowed}.btn-sm.svelte-44iz1r.svelte-44iz1r{padding:4px 10px;font-size:12px}.btn-danger.svelte-44iz1r.svelte-44iz1r{color:#ff6b6b;border-color:#4a2222}.btn-danger.svelte-44iz1r.svelte-44iz1r:hover{background:#3a2222}.files-tab.svelte-44iz1r.svelte-44iz1r{padding:20px}.files-tab.svelte-44iz1r .tab-toolbar.svelte-44iz1r{display:flex;gap:8px;align-items:center;margin-bottom:16px}.file-list.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column}.back-btn.svelte-44iz1r.svelte-44iz1r{margin-bottom:4px;display:inline-flex;align-items:center;gap:4px}.import-summary.svelte-44iz1r.svelte-44iz1r{margin-bottom:16px}.summary-row.svelte-44iz1r.svelte-44iz1r{display:flex;justify-content:space-between;padding:6px 0;font-size:14px;border-bottom:1px solid #2a2a3c}.summary-warn.svelte-44iz1r.svelte-44iz1r{margin-top:8px;padding:8px 12px;background:#3a2a22;border-radius:6px;color:#fa6;font-size:13px}.rename-error.svelte-44iz1r.svelte-44iz1r{color:#ff6b6b;font-size:12px;margin-top:4px}.template-cards.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column;gap:6px;margin-bottom:8px}.template-card.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid #2a2a3c;background:#13131f;color:#ccc;border-radius:8px;cursor:pointer;font-size:13px;font-family:inherit;width:100%;text-align:left}.template-card.svelte-44iz1r.svelte-44iz1r:hover{background:#1e1e30;border-color:#3a3a5c}.template-card.selected.svelte-44iz1r.svelte-44iz1r{background:#2a2a50;border-color:#6366f1;color:#e4e4ef}.template-card-text.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column;gap:2px;min-width:0}.template-card-title.svelte-44iz1r.svelte-44iz1r{font-weight:500}.template-card-desc.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#888}.today-dashboard.svelte-44iz1r.svelte-44iz1r{padding:24px;overflow-y:auto;flex:1}.today-header.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:baseline;gap:12px;margin-bottom:16px}.today-header.svelte-44iz1r h2.svelte-44iz1r{font-size:24px}.today-date.svelte-44iz1r.svelte-44iz1r{font-size:13px;color:#666}.today-summary.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;margin-bottom:20px;flex-wrap:wrap}.summary-chip.svelte-44iz1r.svelte-44iz1r{font-size:12px;color:#b0b0c0;background:#1a1a28;border:1px solid #2a2a3c;padding:4px 12px;border-radius:16px}.today-case.svelte-44iz1r.svelte-44iz1r{background:#1a1a28;border:1px solid #2a2a3c;border-radius:8px;margin-bottom:12px;overflow:hidden}.today-case-header.svelte-44iz1r.svelte-44iz1r{padding:12px 16px;display:flex;align-items:center;gap:8px;border-bottom:1px solid #2a2a3c;cursor:pointer}.today-case-header.svelte-44iz1r.svelte-44iz1r:hover{background:#1e1e30}.today-case-title.svelte-44iz1r.svelte-44iz1r{font-weight:500}.today-case-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#888;background:#223;padding:2px 8px;border-radius:10px}.today-case-count.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#6366f1;margin-left:4px}.today-case-time.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;margin-left:auto}.today-events.svelte-44iz1r.svelte-44iz1r{padding:8px 16px}.today-event.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:13px;color:#b0b0c0;cursor:pointer}.today-event.svelte-44iz1r.svelte-44iz1r:hover{color:#e4e4ef}.today-event-icon.svelte-44iz1r.svelte-44iz1r{width:18px;text-align:center;color:#6366f1;font-size:13px}.today-event-title.svelte-44iz1r.svelte-44iz1r{flex:1}.today-event-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#666}.today-event-time.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;margin-left:auto}.today-events-empty.svelte-44iz1r.svelte-44iz1r{padding:8px 16px;font-size:13px;color:#666;font-style:italic}.today-empty.svelte-44iz1r.svelte-44iz1r{padding:48px 24px;text-align:center}.today-empty.svelte-44iz1r p.svelte-44iz1r{color:#666;font-size:14px;margin:0}.today-empty.svelte-44iz1r .hint.svelte-44iz1r{font-size:12px;color:#555;margin-top:8px}.today-timeline.svelte-44iz1r.svelte-44iz1r{margin-top:24px}.today-timeline.svelte-44iz1r h3.svelte-44iz1r{font-size:13px;color:#666;text-transform:uppercase;margin-bottom:12px}.timeline-event.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:10px;font-size:13px;color:#b0b0c0;border-left:2px solid #2a2a3c;padding:6px 0 6px 16px;margin-left:4px;cursor:pointer}.timeline-event.svelte-44iz1r.svelte-44iz1r:hover{color:#e4e4ef}.timeline-dot.svelte-44iz1r.svelte-44iz1r{width:6px;height:6px;border-radius:50%;background:#6366f1;margin-left:-19px;flex-shrink:0}.timeline-title.svelte-44iz1r.svelte-44iz1r{flex:1}.timeline-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#666}.timeline-time.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555}.activity-tab.svelte-44iz1r.svelte-44iz1r{padding:24px}.activity-events.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column;gap:2px}.activity-event.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;font-size:13px;color:#b0b0c0;cursor:pointer}.activity-event.svelte-44iz1r.svelte-44iz1r:hover{background:#1a1a28;color:#e4e4ef}.activity-event-icon.svelte-44iz1r.svelte-44iz1r{width:18px;text-align:center;color:#6366f1;font-size:13px;flex-shrink:0}.activity-event-title.svelte-44iz1r.svelte-44iz1r{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.activity-event-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#666;flex-shrink:0}.activity-event-target.svelte-44iz1r.svelte-44iz1r{font-size:10px;color:#555;background:#1e1e2e;padding:1px 6px;border-radius:8px;flex-shrink:0}.activity-event-time.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555;margin-left:8px;flex-shrink:0}.activity-feed.svelte-44iz1r.svelte-44iz1r{padding:24px;overflow-y:auto;flex:1}.activity-feed-header.svelte-44iz1r.svelte-44iz1r{margin-bottom:20px}.activity-feed-header.svelte-44iz1r h2.svelte-44iz1r{font-size:24px}.activity-feed-events.svelte-44iz1r.svelte-44iz1r{display:flex;flex-direction:column;gap:2px}.activity-feed-event.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;border-radius:8px;cursor:pointer}.activity-feed-event.svelte-44iz1r.svelte-44iz1r:hover{background:#1a1a28;color:#e4e4ef}.activity-feed-icon.svelte-44iz1r.svelte-44iz1r{width:20px;text-align:center;color:#6366f1;font-size:14px;flex-shrink:0;margin-top:1px}.activity-feed-body.svelte-44iz1r.svelte-44iz1r{flex:1;min-width:0}.activity-feed-title.svelte-44iz1r.svelte-44iz1r{font-size:14px;color:#e4e4ef}.activity-feed-meta.svelte-44iz1r.svelte-44iz1r{display:flex;align-items:center;gap:8px;margin-top:2px}.activity-feed-type.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#666}.activity-feed-target.svelte-44iz1r.svelte-44iz1r{font-size:10px;color:#555;background:#1e1e2e;padding:1px 6px;border-radius:8px}.activity-feed-time.svelte-44iz1r.svelte-44iz1r{font-size:11px;color:#555}.sidebar-sync-btn.svelte-44iz1r.svelte-44iz1r{background:#1e1e38;border:1px solid #6366f1;border-radius:8px;padding:8px 12px;cursor:pointer;width:100%;display:flex;align-items:center;gap:8px;color:#c0c0f0;font-family:inherit;font-size:13px}.sidebar-sync-btn.svelte-44iz1r.svelte-44iz1r:hover{background:#2a2a50;color:#e4e4ef;border-color:#818cf8}.sidebar-sync-label.svelte-44iz1r.svelte-44iz1r{flex:1;text-align:left}.sync-dot.svelte-44iz1r.svelte-44iz1r{width:8px;height:8px;border-radius:50%;background:#4a4a4a;flex-shrink:0}.sync-dot.active.svelte-44iz1r.svelte-44iz1r{background:#4ade80;box-shadow:0 0 6px #4ade8080}.modal-sync.svelte-44iz1r.svelte-44iz1r{width:460px}.sync-status.svelte-44iz1r.svelte-44iz1r{background:#13131f;border-radius:8px;padding:12px;margin-bottom:16px}.sync-row.svelte-44iz1r.svelte-44iz1r{display:flex;justify-content:space-between;padding:4px 0;font-size:13px}.sync-label.svelte-44iz1r.svelte-44iz1r{color:#666}.sync-value.svelte-44iz1r.svelte-44iz1r{color:#e4e4ef}.sync-value.mono.svelte-44iz1r.svelte-44iz1r{font-family:SF Mono,Fira Code,monospace;font-size:12px}.sync-result.svelte-44iz1r.svelte-44iz1r{font-size:12px;color:#6366f1;padding:4px 0}.sync-connected-actions.svelte-44iz1r.svelte-44iz1r{display:flex;gap:8px;margin-bottom:16px} diff --git a/cmd/verstak-gui/frontend-dist/assets/main-wlKdkTmp.js b/cmd/verstak-gui/frontend-dist/assets/main-wlKdkTmp.js new file mode 100644 index 0000000..4257692 --- /dev/null +++ b/cmd/verstak-gui/frontend-dist/assets/main-wlKdkTmp.js @@ -0,0 +1,3 @@ +var _r=Object.defineProperty;var vr=(l,e,t)=>e in l?_r(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var tl=(l,e,t)=>vr(l,typeof e!="symbol"?e+"":e,t);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const s of o)if(s.type==="childList")for(const r of s.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&n(r)}).observe(document,{childList:!0,subtree:!0});function t(o){const s={};return o.integrity&&(s.integrity=o.integrity),o.referrerPolicy&&(s.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?s.credentials="include":o.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function n(o){if(o.ep)return;o.ep=!0;const s=t(o);fetch(o.href,s)}})();function ie(){}function Vi(l){return l()}function Rl(){return Object.create(null)}function me(l){l.forEach(Vi)}function At(l){return typeof l=="function"}function mt(l,e){return l!=l?e==e:l!==e||l&&typeof l=="object"||typeof l=="function"}let Pt;function Rt(l,e){return l===e?!0:(Pt||(Pt=document.createElement("a")),Pt.href=e,l===Pt.href)}function hr(l){return Object.keys(l).length===0}const gr=typeof window<"u"?window:typeof globalThis<"u"?globalThis:global;function c(l,e){l.appendChild(e)}function C(l,e,t){l.insertBefore(e,t||null)}function z(l){l.parentNode&&l.parentNode.removeChild(l)}function Le(l,e){for(let t=0;tl.removeEventListener(e,t,n)}function sl(l){return function(e){return e.preventDefault(),l.call(this,e)}}function lt(l){return function(e){return e.stopPropagation(),l.call(this,e)}}function gt(l){return function(e){e.target===this&&l.call(this,e)}}function i(l,e,t){t==null?l.removeAttribute(e):l.getAttribute(e)!==t&&l.setAttribute(e,t)}function Bt(l){return l===""?null:+l}function br(l){return Array.from(l.childNodes)}function W(l,e){e=""+e,l.data!==e&&(l.data=e)}function Ce(l,e){l.value=e??""}function He(l,e,t,n){t==null?l.style.removeProperty(e):l.style.setProperty(e,t,"")}function Bl(l,e,t){for(let n=0;n{const o=l.$$.callbacks[e];if(o){const s=yr(e,t,{cancelable:n});return o.slice().forEach(r=>{r.call(l,s)}),!s.defaultPrevented}return!0}}function Ui(l,e){const t=l.$$.callbacks[e.type];t&&t.slice().forEach(n=>n.call(this,e))}const wt=[],Vl=[];let zt=[];const Hl=[],wr=Promise.resolve();let nl=!1;function zr(){nl||(nl=!0,wr.then(Wi))}function Vt(l){zt.push(l)}const ll=new Set;let yt=0;function Wi(){if(yt!==0)return;const l=Et;do{try{for(;ytl.indexOf(n)===-1?e.push(n):t.push(n)),t.forEach(n=>n()),zt=e}const Ot=new Set;let ht;function Ye(){ht={r:0,c:[],p:ht}}function Xe(){ht.r||me(ht.c),ht=ht.p}function re(l,e){l&&l.i&&(Ot.delete(l),l.i(e))}function fe(l,e,t,n){if(l&&l.o){if(Ot.has(l))return;Ot.add(l),ht.c.push(()=>{Ot.delete(l),n&&(t&&l.d(1),n())}),l.o(e)}else n&&n()}function ae(l){return(l==null?void 0:l.length)!==void 0?l:Array.from(l)}function Ki(l,e){fe(l,1,1,()=>{e.delete(l.key)})}function Gi(l,e,t,n,o,s,r,a,f,d,h,p){let v=l.length,k=s.length,g=v;const y={};for(;g--;)y[l[g].key]=g;const w=[],S=new Map,M=new Map,T=[];for(g=k;g--;){const N=p(o,s,g),E=t(N);let B=r.get(E);B?T.push(()=>B.p(N,e)):(B=d(E,N),B.c()),S.set(E,w[g]=B),E in y&&M.set(E,Math.abs(g-y[E]))}const j=new Set,D=new Set;function I(N){re(N,1),N.m(a,h),r.set(N.key,N),h=N.first,k--}for(;v&&k;){const N=w[k-1],E=l[v-1],B=N.key,U=E.key;N===E?(h=N.first,v--,k--):S.has(U)?!r.has(B)||j.has(B)?I(N):D.has(U)?v--:M.get(B)>M.get(U)?(D.add(B),I(N)):(j.add(U),v--):(f(E,r),v--)}for(;v--;){const N=l[v];S.has(N.key)||f(N,r)}for(;k;)I(w[k-1]);return me(T),w}function nt(l){l&&l.c()}function et(l,e,t){const{fragment:n,after_update:o}=l.$$;n&&n.m(e,t),Vt(()=>{const s=l.$$.on_mount.map(Vi).filter(At);l.$$.on_destroy?l.$$.on_destroy.push(...s):me(s),l.$$.on_mount=[]}),o.forEach(Vt)}function tt(l,e){const t=l.$$;t.fragment!==null&&(Sr(t.after_update),me(t.on_destroy),t.fragment&&t.fragment.d(e),t.on_destroy=t.fragment=null,t.ctx=[])}function Tr(l,e){l.$$.dirty[0]===-1&&(wt.push(l),zr(),l.$$.dirty.fill(0)),l.$$.dirty[e/31|0]|=1<{const g=k.length?k[0]:v;return d.ctx&&o(d.ctx[p],d.ctx[p]=g)&&(!d.skip_bound&&d.bound[p]&&d.bound[p](g),h&&Tr(l,p)),v}):[],d.update(),h=!0,me(d.before_update),d.fragment=n?n(d.ctx):!1,e.target){if(e.hydrate){const p=br(e.target);d.fragment&&d.fragment.l(p),p.forEach(z)}else d.fragment&&d.fragment.c();e.intro&&re(l.$$.fragment),et(l,e.target,e.anchor),Wi()}Ft(f)}class _t{constructor(){tl(this,"$$");tl(this,"$$set")}$destroy(){tt(this,1),this.$destroy=ie}$on(e,t){if(!At(t))return ie;const n=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return n.push(t),()=>{const o=n.indexOf(t);o!==-1&&n.splice(o,1)}}$set(e){this.$$set&&!hr(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const jr="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(jr);function Nr(l){let e,t;return{c(){e=R("path"),t=R("polyline"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function Mr(l){let e,t,n,o,s;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),s=R("polyline"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","16"),i(n,"y1","13"),i(n,"x2","8"),i(n,"y2","13"),i(o,"x1","16"),i(o,"y1","17"),i(o,"x2","8"),i(o,"y2","17"),i(s,"points","10 9 9 9 8 9")},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),C(r,o,a),C(r,s,a)},d(r){r&&(z(e),z(t),z(n),z(o),z(s))}}}function Dr(l){let e,t;return{c(){e=R("polyline"),t=R("polyline"),i(e,"points","16 18 22 12 16 6"),i(t,"points","8 6 2 12 8 18")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function Ir(l){let e,t,n,o;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("rect"),i(e,"d","M21 8v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8"),i(t,"points","7 3 12 8 17 3"),i(n,"x1","3"),i(n,"y1","8"),i(n,"x2","21"),i(n,"y2","8"),i(o,"x","10"),i(o,"y","12"),i(o,"width","4"),i(o,"height","4"),i(o,"rx","1")},m(s,r){C(s,e,r),C(s,t,r),C(s,n,r),C(s,o,r)},d(s){s&&(z(e),z(t),z(n),z(o))}}}function Fr(l){let e,t,n,o,s;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),s=R("line"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","9"),i(n,"y1","12"),i(n,"x2","15"),i(n,"y2","12"),i(o,"x1","9"),i(o,"y1","15"),i(o,"x2","13"),i(o,"y2","15"),i(s,"x1","12"),i(s,"y1","15"),i(s,"x2","12"),i(s,"y2","18")},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),C(r,o,a),C(r,s,a)},d(r){r&&(z(e),z(t),z(n),z(o),z(s))}}}function Er(l){let e,t,n,o,s,r;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),s=R("line"),r=R("line"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","8"),i(n,"y1","12"),i(n,"x2","16"),i(n,"y2","12"),i(o,"x1","8"),i(o,"y1","16"),i(o,"x2","16"),i(o,"y2","16"),i(s,"x1","8"),i(s,"y1","14"),i(s,"x2","12"),i(s,"y2","14"),i(r,"x1","12"),i(r,"y1","12"),i(r,"x2","12"),i(r,"y2","18")},m(a,f){C(a,e,f),C(a,t,f),C(a,n,f),C(a,o,f),C(a,s,f),C(a,r,f)},d(a){a&&(z(e),z(t),z(n),z(o),z(s),z(r))}}}function Ar(l){let e,t,n,o;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","16"),i(n,"y1","13"),i(n,"x2","8"),i(n,"y2","13"),i(o,"x1","16"),i(o,"y1","17"),i(o,"x2","8"),i(o,"y2","17")},m(s,r){C(s,e,r),C(s,t,r),C(s,n,r),C(s,o,r)},d(s){s&&(z(e),z(t),z(n),z(o))}}}function Lr(l){let e,t,n,o,s;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),s=R("line"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","8"),i(n,"y1","12"),i(n,"x2","16"),i(n,"y2","12"),i(o,"x1","8"),i(o,"y1","16"),i(o,"x2","16"),i(o,"y2","16"),i(s,"x1","8"),i(s,"y1","14"),i(s,"x2","12"),i(s,"y2","14")},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),C(r,o,a),C(r,s,a)},d(r){r&&(z(e),z(t),z(n),z(o),z(s))}}}function Pr(l){let e,t,n;return{c(){e=R("path"),t=R("circle"),n=R("circle"),i(e,"d","M9 18V5l12-2v13"),i(t,"cx","6"),i(t,"cy","18"),i(t,"r","3"),i(n,"cx","18"),i(n,"cy","16"),i(n,"r","3")},m(o,s){C(o,e,s),C(o,t,s),C(o,n,s)},d(o){o&&(z(e),z(t),z(n))}}}function Or(l){let e,t;return{c(){e=R("rect"),t=R("polyline"),i(e,"x","2"),i(e,"y","4"),i(e,"width","20"),i(e,"height","16"),i(e,"rx","2"),i(t,"points","10 9 16 12 10 15 10 9")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function Rr(l){let e,t,n;return{c(){e=R("rect"),t=R("circle"),n=R("polyline"),i(e,"x","3"),i(e,"y","3"),i(e,"width","18"),i(e,"height","18"),i(e,"rx","2"),i(e,"ry","2"),i(t,"cx","8.5"),i(t,"cy","8.5"),i(t,"r","1.5"),i(n,"points","21 15 16 10 5 21")},m(o,s){C(o,e,s),C(o,t,s),C(o,n,s)},d(o){o&&(z(e),z(t),z(n))}}}function Br(l){let e;return{c(){e=R("path"),i(e,"d","M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z")},m(t,n){C(t,e,n)},d(t){t&&z(e)}}}function Vr(l){let e;function t(s,r){return s[0]==="folder"?Br:s[0]==="image"?Rr:s[0]==="video"?Or:s[0]==="audio"?Pr:s[0]==="pdf"?Lr:s[0]==="document"?Ar:s[0]==="spreadsheet"?Er:s[0]==="presentation"?Fr:s[0]==="archive"?Ir:s[0]==="code"?Dr:s[0]==="text"?Mr:Nr}let n=t(l),o=n(l);return{c(){e=R("svg"),o.c(),i(e,"width",l[1]),i(e,"height",l[1]),i(e,"viewBox","0 0 24 24"),i(e,"fill","none"),i(e,"stroke","currentColor"),i(e,"stroke-width","1.5"),i(e,"stroke-linecap","round"),i(e,"stroke-linejoin","round"),i(e,"xmlns","http://www.w3.org/2000/svg")},m(s,r){C(s,e,r),o.m(e,null)},p(s,[r]){n!==(n=t(s))&&(o.d(1),o=n(s),o&&(o.c(),o.m(e,null))),r&2&&i(e,"width",s[1]),r&2&&i(e,"height",s[1])},i:ie,o:ie,d(s){s&&z(e),o.d()}}}function Hr(l,e,t){let{kind:n="generic"}=e,{size:o=20}=e;return l.$$set=s=>{"kind"in s&&t(0,n=s.kind),"size"in s&&t(1,o=s.size)},[n,o]}class qi extends _t{constructor(e){super(),pt(this,e,Hr,Vr,mt,{kind:0,size:1})}}const Ur={"nav.today":"Сегодня","nav.inbox":"Неразобранное","nav.activity":"Активность","nav.journal":"Журнал","nav.clients":"Клиенты","nav.projects":"Проекты","nav.recipes":"Рецепты","nav.documents":"Документы","nav.archive":"Архив","nav.sections":"Разделы","nav.cases":"Дела","nav.noCases":"Нет дел","nav.sync":"Синхронизация","nav.syncSettings":"Настройки синхронизации","nav.syncNow":"Синхронизировать","nav.selectPrompt":"Выберите раздел или дело","nav.brand":"Верстак","nav.system":"Системное","nav.workspace":"Рабочее пространство","nav.noNodes":"Нет узлов","nav.openFolder":"Открыть папку","nav.createInside":"Создать внутри","nav.createNode":"Создать элемент","nav.moveToRoot":"Переместить в корень","tab.overview":"Обзор","tab.notes":"Заметки","tab.files":"Файлы","tab.actions":"Действия","tab.worklog":"Журнал","tab.activity":"Активность","common.save":"Сохранить","common.cancel":"Отмена","common.delete":"Удалить","common.rename":"Переименовать","common.close":"Закрыть","common.create":"Создать","common.confirm":"Подтверждение","common.back":"← Назад","common.loading":"Загрузка...","common.error":"Ошибка:","common.yes":"Да","common.ok":"OK","common.copy":"Копировать","common.cut":"Вырезать","common.paste":"Вставить","common.duplicate":"Дублировать","common.run":"Запустить","common.test":"Test","common.testAgain":"Проверить","common.connect":"Подключиться","common.disconnect":"Отключиться","common.settings":"Настройки","common.name":"Название","common.type":"Тип","common.section":"Раздел","common.created":"Создано","common.empty":"Нет","common.newName":"Новое имя","welcome.title":"Верстак","welcome.selectSection":"Выберите раздел в боковой панели.","welcome.createCase":"Или создайте новое дело кнопкой «+».","welcome.addCase":"Добавить дело","event.noteCreated":"Заметка создана","event.noteUpdated":"Заметка изменена","event.fileAdded":"Файл добавлен","event.fileDeleted":"Файл удалён","event.fileRenamed":"Файл переименован","event.fileCopied":"Файл скопирован","event.fileMoved":"Файл перемещён","event.folderAdded":"Папка добавлена","event.folderDeleted":"Папка удалена","event.folderRenamed":"Папка переименована","event.caseCreated":"Дело создано","event.caseUpdated":"Дело изменено","kind.project":"Проект","kind.client":"Клиент","kind.document":"Документ","kind.recipe":"Рецепт","kind.folder":"Папка","kind.note":"Заметка","kind.file":"Файл","kind.archive":"Архив","kind.case":"Дело","action.openUrl":"Открыть URL","action.openFile":"Открыть файл","action.openFolder":"Открыть папку","action.runCommand":"Запустить команду","action.runScript":"Запустить скрипт","action.openTerminal":"Открыть терминал","action.launchApp":"Запустить приложение","action.addAction":"+ Добавить действие","action.newAction":"Новое действие","action.noActions":"Действий пока нет","action.run":"Запустить","action.dataUrl":"URL","action.dataPath":"Путь","action.dataCommand":"Команда","action.urlPlaceholder":"https://example.com","action.pathPlaceholder":"/path/to/file","action.commandPlaceholder":"команда","action.namePlaceholder":"Например: Открыть сайт","note.add":"+ Добавить заметку","note.new":"Новая заметка","note.title":"Название заметки","note.noNotes":"Нет заметок","note.createFirst":"Создайте первую заметку для этого дела.","note.placeholder":"Начните писать...","note.unsavedTitle":"Несохранённые изменения","note.unsavedMessage":"Закрыть редактор? Все несохранённые изменения будут потеряны.","note.unsavedClose":"Закрыть","file.addFile":"+ Добавить файл","file.addFolder":"+ Добавить папку","file.newFile":"+ Новый файл","file.addFileSimple":"Добавить файл","file.addFolderSimple":"Добавить папку","file.noFiles":"В этой папке пока нет файлов","file.noFilesCase":"В этом проекте пока нет файлов","file.hint":"Добавьте файл или папку, чтобы сохранить материалы проекта.","file.root":"Файлы","file.preview":"Предпросмотр","file.openExternal":"Открыть во внешней программе","file.openFolder":"Открыть папку","file.showInExplorer":"Показать в проводнике","file.more":"Ещё","file.delete":"Удалить","file.ariaFolder":"Папка","file.ariaFile":"Файл","file.scanning":"Сканирование...","file.pickSingle":"Выберите файл","file.pickMultiple":"Выберите файлы","file.pickDirectory":"Выберите папку","file.importTitle":"Добавить в","file.importFiles":"Файлов:","file.importFolders":"Папок:","file.importSize":"Размер:","file.importCopy":"Скопировать","file.importLink":"Привязать","file.selectCaseFirst":"Сначала выберите дело для добавления файлов","worklog.title":"Журнал","worklog.whatDone":"Что сделано","worklog.minutes":"Мин","worklog.min":"мин","worklog.log":"Записать","worklog.empty":"Записей работы пока нет","worklog.suggestions":"Предложения на сегодня","worklog.apply":"Применить","sync.title":"Синхронизация","sync.settings":"Настройки синхронизации","sync.status":"Статус","sync.server":"Сервер","sync.device":"Устройство","sync.deviceId":"ID устройства","sync.unpushed":"Неотправлено","sync.lastSync":"Последняя синх.","sync.revoked":"Отозвано","sync.connected":"Подключено","sync.notConnected":"Не подключено","sync.disabled":"Отключена","sync.serverUrl":"URL сервера","sync.serverUrlPlaceholder":"https://example.com:47732","sync.username":"Логин","sync.usernamePlaceholder":"username","sync.password":"Пароль","sync.passwordPlaceholder":"password","sync.autoSync":"Автосинхронизация (мин, 0 = отключено)","sync.saveInterval":"Сохранить интервал","sync.syncNow":"Синхронизировать","sync.disconnect":"Отключиться","sync.connect":"Подключиться","sync.test":"Проверить","sync.settingsSaved":"интервал сохранён","today.title":"Сегодня","today.changedCases":"Изменён сегодня","today.timeline":"Лента за сегодня","today.empty":"Сегодня пока тихо","today.emptyHint":"Здесь появятся дела, заметки, файлы и действия, с которыми вы работали сегодня.","today.plural.case_one":"дело","today.plural.case_few":"дела","today.plural.case_many":"дел","today.plural.note_one":"заметка","today.plural.note_few":"заметки","today.plural.note_many":"заметок","today.plural.file_one":"файл","today.plural.file_few":"файла","today.plural.file_many":"файлов","today.plural.event_one":"событие","today.plural.event_few":"события","today.plural.event_many":"событий","journal.title":"Журнал работы","journal.empty":"Нет записей за выбранный период","journal.dateFrom":"От","journal.dateTo":"До","journal.filter":"Фильтр","journal.total":"Всего","journal.exportCSV":"CSV","journal.exportMarkdown":"Markdown","journal.billable":"Оплачиваемое","journal.approximate":"Примерно","journal.node":"Дело","journal.path":"Путь","journal.byDay":"По дням","journal.byNode":"По делам","journal.includeChildren":"С подзадачами","suggest.title":"Предложения на сегодня","suggest.apply":"Записать","suggest.dismiss":"Скрыть","suggest.open":"Открыть","suggest.confidence.low":"Низкая уверенность","suggest.confidence.medium":"Средняя уверенность","suggest.confidence.high":"Высокая уверенность","suggest.minutes":"мин","suggest.edit":"Изменить","suggest.noSuggestions":"Нет предложений для журнала","activity.title":"Активность","activity.empty":"Активность пока не зафиксирована","activity.perCaseEmpty":"Активность пока не зафиксирована","overview.type":"Тип","overview.section":"Раздел","overview.created":"Создано","overview.newNote":"Новая заметка","overview.addFile":"Добавить файл","overview.addAction":"Добавить действие","overview.logTime":"Записать время","overview.recentNotes":"Последние заметки","overview.recentEntries":"Последние записи","rename.title":"Переименовать","rename.emptyError":"Имя не может быть пустым","rename.invalidError":"Недопустимое имя","delete.confirmTitle":"Удаление","delete.confirmMessage":"Удалить","delete.folder":"папку","delete.file":"файл","template.optionNone":"Пустое дело","template.optional":"Шаблон (опционально)","template.none.desc":"Без шаблона, простой узел-контейнер","template.folder":"Папка","template.folder.desc":"Папка для группировки элементов внутри рабочего пространства","template.project":"Проект","template.project.desc":"Отдельный проект или задача с файлами, заметками и журналом","template.client":"Клиент","template.client.desc":"Организация или человек, для которых ведутся работы","template.document":"Документ","template.document.desc":"Документ с описанием, заметками и файлами","template.recipe":"Рецепт","template.recipe.desc":"Повторяемая процедура или инструкция","template.note":"Заметка","template.file":"Файл","template.select":"Выберите тип","mime.jpeg":"Изображение JPEG","mime.png":"Изображение PNG","mime.gif":"Изображение GIF","mime.webp":"Изображение WebP","mime.svg":"Изображение SVG","mime.bmp":"Изображение BMP","mime.tiff":"Изображение TIFF","mime.avif":"Изображение AVIF","mime.pdf":"PDF документ","mime.word":"Документ Word","mime.excel":"Таблица Excel","mime.ppt":"Презентация PowerPoint","mime.zip":"ZIP архив","mime.gzip":"GZIP архив","mime.tar":"TAR архив","mime.sevenz":"7z архив","mime.rar":"RAR архив","mime.text":"Текстовый файл","mime.html":"HTML файл","mime.css":"CSS файл","mime.js":"JavaScript файл","mime.json":"JSON файл","mime.xml":"XML файл","mime.yaml":"YAML файл","mime.binary":"Бинарный файл","mime.executable":"Исполняемый файл","mime.folder":"Папка","mime.unknown":"Неизвестно","mime.file":"Файл","error.nameEmpty":"Имя не может быть пустым","error.nameInvalid":"Недопустимое имя","error.selectCaseFirst":"Сначала выберите дело","common.open":"Открыть","delete.files":"файлов ({count})","file.namePrompt":"Введите имя файла:","file.pdfUnavailable":"Предпросмотр PDF недоступен.","file.previewUnavailable":"Предпросмотр недоступен для этого типа файлов.","case.new":"Новое дело","case.namePlaceholder":"Название дела","error.generic":"Произошла ошибка","error.invalidCredentials":"Неверный логин или пароль","error.accountBlocked":"Аккаунт заблокирован","error.emailNotConfirmed":"Email не подтверждён","error.tokenInvalid":"Неверный или просроченный токен","error.tokenExpired":"Срок действия токена истёк"},Wr={"nav.today":"Today","nav.inbox":"Inbox","nav.activity":"Activity","nav.clients":"Clients","nav.projects":"Projects","nav.recipes":"Recipes","nav.documents":"Documents","nav.archive":"Archive","nav.sections":"Sections","nav.cases":"Cases","nav.noCases":"No cases","nav.system":"System","nav.workspace":"Workspace","nav.noNodes":"No nodes","nav.openFolder":"Open folder","nav.createInside":"Create inside","nav.createNode":"Create element","nav.moveToRoot":"Move to root","nav.selectPrompt":"Select a section or case","nav.brand":"Verstak","tab.overview":"Overview","tab.notes":"Notes","tab.files":"Files","tab.actions":"Actions","tab.worklog":"Work Log","tab.activity":"Activity","common.save":"Save","common.cancel":"Cancel","common.delete":"Delete","common.rename":"Rename","common.close":"Close","common.create":"Create","common.confirm":"Confirm","common.back":"← Back","common.loading":"Loading...","common.error":"Error:","common.yes":"Yes","common.ok":"OK","common.run":"Run","common.name":"Name","common.settings":"Settings","welcome.title":"Verstak","welcome.selectSection":"Select a section in the sidebar.","welcome.addCase":"Add case","event.noteCreated":"Note created","event.noteUpdated":"Note updated","event.fileAdded":"File added","event.fileDeleted":"File deleted","event.fileRenamed":"File renamed","event.fileCopied":"File copied","event.fileMoved":"File moved","event.caseCreated":"Case created","action.openUrl":"Open URL","action.openFile":"Open file","action.openFolder":"Open folder","action.runCommand":"Run command","action.runScript":"Run script","action.openTerminal":"Open terminal","action.launchApp":"Launch app","note.add":"+ Add note","note.noNotes":"No notes","note.title":"Note title","note.placeholder":"Start writing...","file.addFile":"+ Add file","file.addFolder":"+ Add folder","file.preview":"Preview","file.openExternal":"Open in external program","file.openFolder":"Open folder","file.showInExplorer":"Show in explorer","file.delete":"Delete","file.pickSingle":"Select file","file.pickDirectory":"Select folder","sync.title":"Sync","sync.settings":"Sync settings","sync.status":"Status","sync.server":"Server","sync.device":"Device","sync.connected":"Connected","sync.notConnected":"Not connected","sync.disabled":"Disabled","kind.project":"Project","kind.client":"Client","kind.document":"Document","kind.recipe":"Recipe","kind.folder":"Folder","kind.note":"Note","kind.file":"File","kind.archive":"Archive","kind.case":"Case","template.optionNone":"Empty case","template.optional":"Template (optional)","template.none.desc":"No template, simple container node","template.folder":"Folder","template.folder.desc":"A folder to group items inside a workspace","template.project":"Project","template.project.desc":"A distinct project or task with files, notes and work log","template.client":"Client","template.client.desc":"An organization or person for whom work is performed","template.document":"Document","template.document.desc":"A document with description, notes and files","template.recipe":"Recipe","template.recipe.desc":"A repeatable procedure or instruction","template.note":"Note","template.file":"File","template.select":"Select type","case.new":"New case","case.namePlaceholder":"Case name","error.generic":"An error occurred","error.invalidCredentials":"Invalid username or password","worklog.suggestions":"Suggestions for today","worklog.apply":"Apply","nav.journal":"Journal","journal.title":"Work Log","journal.empty":"No entries for the selected period","journal.dateFrom":"From","journal.dateTo":"To","journal.filter":"Filter","journal.total":"Total","journal.exportCSV":"CSV","journal.exportMarkdown":"Markdown","journal.billable":"Billable","journal.approximate":"Approx","journal.node":"Case","journal.path":"Path","journal.byDay":"By day","journal.byNode":"By case","journal.includeChildren":"Include subtasks","suggest.title":"Suggestions","suggest.apply":"Log","suggest.dismiss":"Dismiss","suggest.open":"Open","suggest.confidence.low":"Low confidence","suggest.confidence.medium":"Medium confidence","suggest.confidence.high":"High confidence","suggest.minutes":"min","suggest.edit":"Edit","suggest.noSuggestions":"No suggestions"},Ul={ru:Ur,en:Wr};let Wl="ru";function _(l,e){var o;const t=Ul[Wl];let n=t==null?void 0:t[l];if(n==null&&Wl!=="ru"&&(n=(o=Ul.ru)==null?void 0:o[l]),n==null&&(n=l),e!=null)for(const[s,r]of Object.entries(e))n=n.replace(`{${s}}`,String(r));return n}function Ht(l){if(l==null||l<0)return"—";if(l===0)return"0 B";const e=["B","KB","MB","GB"],t=Math.min(Math.floor(Math.log(l)/Math.log(1024)),e.length-1),n=l/Math.pow(1024,t);return(t===0?n.toFixed(0):n.toFixed(1))+" "+e[t]}const il={"image/jpeg":_("mime.jpeg"),"image/png":_("mime.png"),"image/gif":_("mime.gif"),"image/webp":_("mime.webp"),"image/svg+xml":_("mime.svg"),"image/bmp":_("mime.bmp"),"image/tiff":_("mime.tiff"),"image/avif":_("mime.avif"),"application/pdf":_("mime.pdf"),"application/msword":_("mime.word"),"application/vnd.openxmlformats-officedocument.wordprocessingml.document":_("mime.word"),"application/vnd.ms-excel":_("mime.excel"),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":_("mime.excel"),"application/vnd.ms-powerpoint":_("mime.ppt"),"application/vnd.openxmlformats-officedocument.presentationml.presentation":_("mime.ppt"),"application/zip":_("mime.zip"),"application/gzip":_("mime.gzip"),"application/x-tar":_("mime.tar"),"application/x-7z-compressed":_("mime.sevenz"),"application/x-rar-compressed":_("mime.rar"),"text/plain":_("mime.text"),"text/html":_("mime.html"),"text/css":_("mime.css"),"text/javascript":_("mime.js"),"application/json":_("mime.json"),"application/xml":_("mime.xml"),"application/x-yaml":_("mime.yaml"),"application/octet-stream":_("mime.binary"),"application/x-msdos-program":_("mime.executable"),"inode/directory":_("mime.folder")};function Kl(l){return l?il[l]||l:_("mime.unknown")}function Kr(l){if(l.type==="folder")return _("mime.folder");const e=(l.mime||"").toLowerCase();if(il[e])return il[e];const n=(l.name||"").toLowerCase().split(".").pop();return n?n.toUpperCase():_("mime.file")}function Ji(l){if(l.type==="folder")return"folder";const e=(l.mime||"").toLowerCase();if(e.startsWith("image/"))return"image";if(e.startsWith("video/"))return"video";if(e.startsWith("audio/"))return"audio";if(e.startsWith("text/"))return"text";if(e.includes("pdf"))return"pdf";if(e.includes("word")||e.includes("document"))return"document";if(e.includes("spreadsheet")||e.includes("excel"))return"spreadsheet";if(e.includes("presentation")||e.includes("powerpoint"))return"presentation";if(e.includes("zip")||e.includes("tar")||e.includes("gzip")||e.includes("rar")||e.includes("7z")||e.includes("compress"))return"archive";if(e.includes("json")||e.includes("xml")||e.includes("yaml")||e.includes("javascript")||e.includes("css")||e.includes("html"))return"code";const n=(l.name||"").toLowerCase().split(".").pop();return["js","ts","jsx","tsx","vue","svelte","py","rs","go","c","cpp","h","hpp","java","kt","swift","rb","php","pl","sh","bash","zsh","fish","yml","yaml","json","xml","toml","ini","cfg","conf","md","markdown","css","scss","less","sass","sql","graphql","proto","gradle","cmake","makefile","dockerfile","env","gitignore"].includes(n)?"code":"generic"}const Gr=["image/jpeg","image/png","image/gif","image/webp","image/bmp","image/tiff","image/avif","image/svg+xml"],qr=["text/plain","text/html","text/css","text/javascript","application/json","application/xml","application/x-yaml","text/x-shellscript"],Jr=["txt","log","conf","ini","yaml","yml","json","xml","csv","sh","py","js","ts","css","html","md","markdown","cfg"],Yr=["jpg","jpeg","png","gif","webp","bmp","tiff","tif","avif","svg"];function Yi(l){const e=(l.mime||"").toLowerCase(),n=(l.name||"").toLowerCase().split(".").pop();return Gr.includes(e)||Yr.includes(n)}function Xi(l){const e=(l.mime||"").toLowerCase(),n=(l.name||"").toLowerCase().split(".").pop();return qr.includes(e)||Jr.includes(n)&&n!=="md"&&n!=="markdown"}function Zi(l){return(l.mime||"").toLowerCase().includes("pdf")}function Qi(l){const e=(l.name||"").toLowerCase();return e.endsWith(".md")||e.endsWith(".markdown")}function Xr(l){return Yi(l)||Zi(l)}function Zr(l){return Xi(l)||Qi(l)}const{window:Qr}=gr;function xr(l){let e,t,n,o=Ht(l[0].size)+"",s;return{c(){e=u("span"),e.textContent="·",t=b(),n=u("span"),s=F(o),i(e,"class","meta-sep svelte-1skuef2")},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),c(n,s)},p(r,a){a[0]&1&&o!==(o=Ht(r[0].size)+"")&&W(s,o)},d(r){r&&(z(e),z(t),z(n))}}}function $r(l){let e,t,n,o,s;return{c(){e=u("button"),e.innerHTML='',t=b(),n=u("button"),n.innerHTML='',i(e,"class","action-btn svelte-1skuef2"),i(e,"title",_("file.openFolder")),i(e,"aria-label",_("file.openFolder")),i(n,"class","action-btn svelte-1skuef2"),i(n,"title",_("file.showInExplorer")),i(n,"aria-label",_("file.showInExplorer"))},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),o||(s=[L(e,"click",lt(l[30])),L(n,"click",lt(l[11]))],o=!0)},p:ie,d(r){r&&(z(e),z(t),z(n)),o=!1,me(s)}}}function ec(l){let e,t,n,o,s,r,a;return{c(){e=u("button"),e.innerHTML='',t=b(),n=u("button"),n.innerHTML='',o=b(),s=u("button"),s.innerHTML='',i(e,"class","action-btn svelte-1skuef2"),i(e,"title",_("file.preview")),i(e,"aria-label",_("file.preview")),i(n,"class","action-btn svelte-1skuef2"),i(n,"title",_("file.openExternal")),i(n,"aria-label",_("file.openExternal")),i(s,"class","action-btn svelte-1skuef2"),i(s,"title",_("file.showInExplorer")),i(s,"aria-label",_("file.showInExplorer"))},m(f,d){C(f,e,d),C(f,t,d),C(f,n,d),C(f,o,d),C(f,s,d),r||(a=[L(e,"click",lt(l[29])),L(n,"click",lt(l[10])),L(s,"click",lt(l[11]))],r=!0)},p:ie,d(f){f&&(z(e),z(t),z(n),z(o),z(s)),r=!1,me(a)}}}function Gl(l){let e,t,n,o,s,r,a,f,d=_("common.open")+"",h,p,v,k,g,y,w,S,M=_("file.openExternal")+"",T,j,D,I,N,E,B=_("file.showInExplorer")+"",U,K,O,G,q,H,Z,J,X,Y=_("common.rename")+"",P,ee,ve,te,le,oe,_e,Me=_("common.duplicate")+"",Ie,Ze,Re,V,Q,de,ce,ue,he,Ke=_("common.cut")+"",Qe,qe,ge,ye,se,Se,Fe,Ne=_("common.copy")+"",De,Ue,Be,ut,Pe,We,Te,je,Ee,Ae=_("common.delete")+"",Oe,be,ze;return{c(){e=u("div"),t=b(),n=u("div"),o=u("button"),s=R("svg"),r=R("path"),a=R("circle"),f=b(),h=F(d),p=b(),v=u("button"),k=R("svg"),g=R("path"),y=R("polyline"),w=R("line"),S=b(),T=F(M),j=b(),D=u("button"),I=R("svg"),N=R("path"),E=b(),U=F(B),K=b(),O=u("div"),G=b(),q=u("button"),H=R("svg"),Z=R("path"),J=R("path"),X=b(),P=F(Y),ee=b(),ve=u("button"),te=R("svg"),le=R("rect"),oe=R("path"),_e=b(),Ie=F(Me),Ze=b(),Re=u("button"),V=R("svg"),Q=R("circle"),de=R("circle"),ce=R("line"),ue=R("line"),he=b(),Qe=F(Ke),qe=b(),ge=u("button"),ye=R("svg"),se=R("rect"),Se=R("path"),Fe=b(),De=F(Ne),Ue=b(),Be=u("div"),ut=b(),Pe=u("button"),We=R("svg"),Te=R("polyline"),je=R("path"),Ee=b(),Oe=F(Ae),i(e,"class","menu-backdrop svelte-1skuef2"),i(e,"role","presentation"),i(r,"d","M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"),i(a,"cx","12"),i(a,"cy","12"),i(a,"r","3"),i(s,"width","14"),i(s,"height","14"),i(s,"viewBox","0 0 24 24"),i(s,"fill","none"),i(s,"stroke","currentColor"),i(s,"stroke-width","2"),i(s,"stroke-linecap","round"),i(s,"stroke-linejoin","round"),i(o,"class","menu-item svelte-1skuef2"),i(o,"role","menuitem"),i(g,"d","M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"),i(y,"points","15 3 21 3 21 9"),i(w,"x1","10"),i(w,"y1","14"),i(w,"x2","21"),i(w,"y2","3"),i(k,"width","14"),i(k,"height","14"),i(k,"viewBox","0 0 24 24"),i(k,"fill","none"),i(k,"stroke","currentColor"),i(k,"stroke-width","2"),i(k,"stroke-linecap","round"),i(k,"stroke-linejoin","round"),i(v,"class","menu-item svelte-1skuef2"),i(v,"role","menuitem"),i(N,"d","M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"),i(I,"width","14"),i(I,"height","14"),i(I,"viewBox","0 0 24 24"),i(I,"fill","none"),i(I,"stroke","currentColor"),i(I,"stroke-width","2"),i(I,"stroke-linecap","round"),i(I,"stroke-linejoin","round"),i(D,"class","menu-item svelte-1skuef2"),i(D,"role","menuitem"),i(O,"class","menu-sep svelte-1skuef2"),i(Z,"d","M12 20h9"),i(J,"d","M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"),i(H,"width","14"),i(H,"height","14"),i(H,"viewBox","0 0 24 24"),i(H,"fill","none"),i(H,"stroke","currentColor"),i(H,"stroke-width","2"),i(H,"stroke-linecap","round"),i(H,"stroke-linejoin","round"),i(q,"class","menu-item svelte-1skuef2"),i(q,"role","menuitem"),i(le,"x","9"),i(le,"y","9"),i(le,"width","13"),i(le,"height","13"),i(le,"rx","2"),i(le,"ry","2"),i(oe,"d","M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"),i(te,"width","14"),i(te,"height","14"),i(te,"viewBox","0 0 24 24"),i(te,"fill","none"),i(te,"stroke","currentColor"),i(te,"stroke-width","2"),i(te,"stroke-linecap","round"),i(te,"stroke-linejoin","round"),i(ve,"class","menu-item svelte-1skuef2"),i(ve,"role","menuitem"),i(Q,"cx","6"),i(Q,"cy","6"),i(Q,"r","3"),i(de,"cx","6"),i(de,"cy","18"),i(de,"r","3"),i(ce,"x1","20"),i(ce,"y1","4"),i(ce,"x2","8.12"),i(ce,"y2","15.88"),i(ue,"x1","8.12"),i(ue,"y1","8.12"),i(ue,"x2","20"),i(ue,"y2","20"),i(V,"width","14"),i(V,"height","14"),i(V,"viewBox","0 0 24 24"),i(V,"fill","none"),i(V,"stroke","currentColor"),i(V,"stroke-width","2"),i(V,"stroke-linecap","round"),i(V,"stroke-linejoin","round"),i(Re,"class","menu-item svelte-1skuef2"),i(Re,"role","menuitem"),i(se,"x","9"),i(se,"y","9"),i(se,"width","13"),i(se,"height","13"),i(se,"rx","2"),i(se,"ry","2"),i(Se,"d","M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"),i(ye,"width","14"),i(ye,"height","14"),i(ye,"viewBox","0 0 24 24"),i(ye,"fill","none"),i(ye,"stroke","currentColor"),i(ye,"stroke-width","2"),i(ye,"stroke-linecap","round"),i(ye,"stroke-linejoin","round"),i(ge,"class","menu-item svelte-1skuef2"),i(ge,"role","menuitem"),i(Be,"class","menu-sep svelte-1skuef2"),i(Te,"points","3 6 5 6 21 6"),i(je,"d","M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"),i(We,"width","14"),i(We,"height","14"),i(We,"viewBox","0 0 24 24"),i(We,"fill","none"),i(We,"stroke","currentColor"),i(We,"stroke-width","2"),i(We,"stroke-linecap","round"),i(We,"stroke-linejoin","round"),i(Pe,"class","menu-item menu-item-danger svelte-1skuef2"),i(Pe,"role","menuitem"),i(n,"class","menu svelte-1skuef2"),He(n,"left",l[3]+"px"),He(n,"top",l[4]+"px"),He(n,"position","fixed"),i(n,"role","menu"),i(n,"tabindex","-1")},m(Ge,x){C(Ge,e,x),C(Ge,t,x),C(Ge,n,x),c(n,o),c(o,s),c(s,r),c(s,a),c(o,f),c(o,h),c(n,p),c(n,v),c(v,k),c(k,g),c(k,y),c(k,w),c(v,S),c(v,T),c(n,j),c(n,D),c(D,I),c(I,N),c(D,E),c(D,U),c(n,K),c(n,O),c(n,G),c(n,q),c(q,H),c(H,Z),c(H,J),c(q,X),c(q,P),c(n,ee),c(n,ve),c(ve,te),c(te,le),c(te,oe),c(ve,_e),c(ve,Ie),c(n,Ze),c(n,Re),c(Re,V),c(V,Q),c(V,de),c(V,ce),c(V,ue),c(Re,he),c(Re,Qe),c(n,qe),c(n,ge),c(ge,ye),c(ye,se),c(ye,Se),c(ge,Fe),c(ge,De),c(n,Ue),c(n,Be),c(n,ut),c(n,Pe),c(Pe,We),c(We,Te),c(We,je),c(Pe,Ee),c(Pe,Oe),be||(ze=[L(e,"click",lt(l[19])),L(o,"click",l[17]),L(v,"click",l[10]),L(D,"click",l[11]),L(q,"click",l[13]),L(ve,"click",l[14]),L(Re,"click",l[15]),L(ge,"click",l[16]),L(Pe,"click",l[12]),L(n,"click",lt(l[28])),L(n,"keydown",l[31])],be=!0)},p(Ge,x){x[0]&8&&He(n,"left",Ge[3]+"px"),x[0]&16&&He(n,"top",Ge[4]+"px")},d(Ge){Ge&&(z(e),z(t),z(n)),be=!1,me(ze)}}}function tc(l){let e,t,n,o,s,r,a=l[0].name+"",f,d,h,p,v,k,g,y,w,S,M,T,j,D,I,N,E,B,U,K,O,G;n=new qi({props:{kind:l[6],size:22}});let q=!l[7]&&xr(l);function H(Y,P){return Y[7]?$r:ec}let J=H(l)(l),X=l[2]&&Gl(l);return{c(){e=u("div"),t=u("div"),nt(n.$$.fragment),o=b(),s=u("div"),r=u("div"),f=F(a),h=b(),p=u("div"),v=u("span"),v.textContent=`${l[8]}`,k=b(),q&&q.c(),g=b(),y=u("div"),J.c(),w=b(),S=u("button"),M=R("svg"),T=R("circle"),j=R("circle"),D=R("circle"),I=b(),N=u("button"),N.innerHTML='',B=b(),X&&X.c(),U=rt(),i(t,"class","file-row-icon svelte-1skuef2"),i(r,"class","file-row-name svelte-1skuef2"),i(r,"title",d=l[0].name),i(p,"class","file-row-meta svelte-1skuef2"),i(s,"class","file-row-body svelte-1skuef2"),i(T,"cx","12"),i(T,"cy","5"),i(T,"r","2"),i(j,"cx","12"),i(j,"cy","12"),i(j,"r","2"),i(D,"cx","12"),i(D,"cy","19"),i(D,"r","2"),i(M,"width","16"),i(M,"height","16"),i(M,"viewBox","0 0 24 24"),i(M,"fill","currentColor"),i(S,"class","action-btn svelte-1skuef2"),i(S,"title",_("file.more")),i(S,"aria-label",_("file.more")),i(S,"aria-expanded",l[2]),i(N,"class","action-btn action-btn-danger svelte-1skuef2"),i(N,"title",_("common.delete")),i(N,"aria-label",_("common.delete")),i(y,"class","file-row-actions svelte-1skuef2"),i(e,"class","file-row svelte-1skuef2"),i(e,"role","button"),i(e,"tabindex","0"),i(e,"draggable","true"),i(e,"aria-label",E=l[7]?_("file.ariaFolder")+" "+l[0].name:_("file.ariaFile")+" "+l[0].name),we(e,"file-row--selected",l[1])},m(Y,P){C(Y,e,P),c(e,t),et(n,t,null),c(e,o),c(e,s),c(s,r),c(r,f),c(s,h),c(s,p),c(p,v),c(p,k),q&&q.m(p,null),c(e,g),c(e,y),J.m(y,null),c(y,w),c(y,S),c(S,M),c(M,T),c(M,j),c(M,D),c(y,I),c(y,N),C(Y,B,P),X&&X.m(Y,P),C(Y,U,P),K=!0,O||(G=[L(Qr,"click",l[19]),L(S,"click",lt(l[18])),L(N,"click",lt(l[12])),L(e,"click",l[9]),L(e,"keydown",l[24]),L(e,"contextmenu",l[23]),L(e,"dragstart",l[20]),L(e,"dragover",l[21]),L(e,"drop",l[22])],O=!0)},p(Y,P){(!K||P[0]&1)&&a!==(a=Y[0].name+"")&&W(f,a),(!K||P[0]&1&&d!==(d=Y[0].name))&&i(r,"title",d),Y[7]||q.p(Y,P),J.p(Y,P),(!K||P[0]&4)&&i(S,"aria-expanded",Y[2]),(!K||P[0]&1&&E!==(E=Y[7]?_("file.ariaFolder")+" "+Y[0].name:_("file.ariaFile")+" "+Y[0].name))&&i(e,"aria-label",E),(!K||P[0]&2)&&we(e,"file-row--selected",Y[1]),Y[2]?X?X.p(Y,P):(X=Gl(Y),X.c(),X.m(U.parentNode,U)):X&&(X.d(1),X=null)},i(Y){K||(re(n.$$.fragment,Y),K=!0)},o(Y){fe(n.$$.fragment,Y),K=!1},d(Y){Y&&(z(e),z(B),z(U)),tt(n),q&&q.d(),J.d(),X&&X.d(Y),O=!1,me(G)}}}function lc(l,e,t){let{item:n}=e,{selected:o=!1}=e,{onDragStart:s}=e,{onDragOver:r}=e,{onDrop:a}=e;const f=Ut(),d=Ji(n),h=n.type==="folder",p=Kr(n);let v=!1,k=0,g=0,y=null;function w(P){P.ctrlKey||P.metaKey?f("toggleSelect",n.id):P.shiftKey?f("rangeSelect",n.id):y?(clearTimeout(y),y=null,h?f("navigate",n.id):f("preview",n)):y=setTimeout(()=>{y=null,f("selectOne",n.id)},250)}function S(){f("openExternal",n.fileId)}function M(){t(2,v=!1),f("showInFolder",n.nodeId||n.id)}function T(){t(2,v=!1),f("delete",{id:n.id,type:n.type})}function j(){t(2,v=!1),f("rename",{id:n.id,name:n.name})}function D(){t(2,v=!1),f("duplicate",n.id)}function I(){t(2,v=!1),f("cut",n.id)}function N(){t(2,v=!1),f("copy",n.id)}function E(){t(2,v=!1),h?f("navigate",n.id):f("preview",n)}function B(){t(2,v=!v)}function U(){t(2,v=!1)}function K(P){s&&s(P,n.id)}function O(P){r&&h&&r(P,n.id)}function G(P){a&&h&&a(P,n.id)}function q(P){P.preventDefault(),t(3,k=Math.min(P.clientX,window.innerWidth-240)),t(4,g=Math.min(P.clientY,window.innerHeight-320)),t(2,v=!0)}function H(P){(P.key==="Enter"||P.key===" ")&&(P.preventDefault(),w(P))}function Z(P){Ui.call(this,l,P)}const J=()=>f("preview",n),X=()=>f("navigate",n.id),Y=P=>{P.key==="Escape"&&(P.stopPropagation(),U())};return l.$$set=P=>{"item"in P&&t(0,n=P.item),"selected"in P&&t(1,o=P.selected),"onDragStart"in P&&t(25,s=P.onDragStart),"onDragOver"in P&&t(26,r=P.onDragOver),"onDrop"in P&&t(27,a=P.onDrop)},[n,o,v,k,g,f,d,h,p,w,S,M,T,j,D,I,N,E,B,U,K,O,G,q,H,s,r,a,Z,J,X,Y]}class nc extends _t{constructor(e){super(),pt(this,e,lc,tc,mt,{item:0,selected:1,onDragStart:25,onDragOver:26,onDrop:27},null,[-1,-1])}}function ql(l,e,t){const n=l.slice();return n[4]=e[t],n[6]=t,n}function ic(l){let e;return{c(){e=u("span"),e.textContent="/",i(e,"class","sep svelte-csi2lb")},m(t,n){C(t,e,n)},d(t){t&&z(e)}}}function oc(l){let e,t=l[4].name+"",n,o,s;function r(){return l[2](l[6])}return{c(){e=u("button"),n=F(t),i(e,"class","crumb crumb--link svelte-csi2lb")},m(a,f){C(a,e,f),c(e,n),o||(s=L(e,"click",r),o=!0)},p(a,f){l=a,f&1&&t!==(t=l[4].name+"")&&W(n,t)},d(a){a&&z(e),o=!1,s()}}}function sc(l){let e,t=l[4].name+"",n;return{c(){e=u("span"),n=F(t),i(e,"class","crumb crumb--current svelte-csi2lb")},m(o,s){C(o,e,s),c(e,n)},p(o,s){s&1&&t!==(t=o[4].name+"")&&W(n,t)},d(o){o&&z(e)}}}function Jl(l){let e,t,n=l[6]>0&&ic();function o(a,f){return a[6]===a[0].length-1?sc:oc}let s=o(l),r=s(l);return{c(){n&&n.c(),e=b(),r.c(),t=rt()},m(a,f){n&&n.m(a,f),C(a,e,f),r.m(a,f),C(a,t,f)},p(a,f){s===(s=o(a))&&r?r.p(a,f):(r.d(1),r=s(a),r&&(r.c(),r.m(t.parentNode,t)))},d(a){a&&(z(e),z(t)),n&&n.d(a),r.d(a)}}}function rc(l){let e,t=ae(l[0]),n=[];for(let o=0;os(a);return l.$$set=a=>{"crumbs"in a&&t(0,n=a.crumbs)},[n,s,r]}class xi extends _t{constructor(e){super(),pt(this,e,cc,rc,mt,{crumbs:0})}}function ac(l){let e,t,n,o,s,r;return{c(){e=u("div"),t=u("p"),t.textContent=`${_("file.previewUnavailable")}`,n=b(),o=u("button"),o.textContent=`${_("file.openExternal")}`,i(o,"class","btn btn-sm svelte-1cw3u0m"),i(e,"class","preview-status svelte-1cw3u0m")},m(a,f){C(a,e,f),c(e,t),c(e,n),c(e,o),s||(r=L(o,"click",l[9]),s=!0)},p:ie,d(a){a&&z(e),s=!1,r()}}}function fc(l){let e,t;function n(r,a){return a&2&&(e=null),e==null&&(e=!!(r[1]&&r[1].startsWith("data:"))),e?vc:_c}let o=n(l,-1),s=o(l);return{c(){s.c(),t=rt()},m(r,a){s.m(r,a),C(r,t,a)},p(r,a){o===(o=n(r,a))&&s?s.p(r,a):(s.d(1),s=o(r),s&&(s.c(),s.m(t.parentNode,t)))},d(r){r&&z(t),s.d(r)}}}function uc(l){let e,t,n;return{c(){e=u("pre"),t=u("code"),n=F(l[1]),i(e,"class","preview-text svelte-1cw3u0m")},m(o,s){C(o,e,s),c(e,t),c(t,n)},p(o,s){s&2&&W(n,o[1])},d(o){o&&z(e)}}}function dc(l){let e,t,n,o;return{c(){e=u("div"),t=u("img"),Rt(t.src,n=l[1])||i(t,"src",n),i(t,"alt",o=l[0].name),i(t,"class","preview-image svelte-1cw3u0m"),i(e,"class","preview-image-container svelte-1cw3u0m")},m(s,r){C(s,e,r),c(e,t)},p(s,r){r&2&&!Rt(t.src,n=s[1])&&i(t,"src",n),r&1&&o!==(o=s[0].name)&&i(t,"alt",o)},d(s){s&&z(e)}}}function mc(l){let e,t,n,o,s,r,a;return{c(){e=u("div"),t=u("p"),n=F(l[3]),o=b(),s=u("button"),s.textContent=`${_("file.openExternal")}`,i(s,"class","btn btn-sm svelte-1cw3u0m"),i(e,"class","preview-status svelte-1cw3u0m")},m(f,d){C(f,e,d),c(e,t),c(t,n),c(e,o),c(e,s),r||(a=L(s,"click",l[9]),r=!0)},p(f,d){d&8&&W(n,f[3])},d(f){f&&z(e),r=!1,a()}}}function pc(l){let e,t;return{c(){e=u("div"),t=u("p"),t.textContent=`${_("common.loading")}`,i(e,"class","preview-status svelte-1cw3u0m")},m(n,o){C(n,e,o),c(e,t)},p:ie,d(n){n&&z(e)}}}function _c(l){let e,t,n,o,s,r;return{c(){e=u("div"),t=u("p"),t.textContent=`${_("file.pdfUnavailable")}`,n=b(),o=u("button"),o.textContent=`${_("file.openExternal")}`,i(o,"class","btn btn-sm svelte-1cw3u0m"),i(e,"class","preview-status svelte-1cw3u0m")},m(a,f){C(a,e,f),c(e,t),c(e,n),c(e,o),s||(r=L(o,"click",l[9]),s=!0)},p:ie,d(a){a&&z(e),s=!1,r()}}}function vc(l){let e,t,n;return{c(){e=u("div"),t=u("embed"),Rt(t.src,n=l[1])||i(t,"src",n),i(t,"type","application/pdf"),i(t,"class","preview-pdf svelte-1cw3u0m"),i(e,"class","preview-pdf-container svelte-1cw3u0m")},m(o,s){C(o,e,s),c(e,t)},p(o,s){s&2&&!Rt(t.src,n=o[1])&&i(t,"src",n)},d(o){o&&z(e)}}}function hc(l){let e,t,n,o,s,r,a,f=l[0].name+"",d,h,p,v,k=Ht(l[0].size)+"",g,y,w=Kl(l[0].mime)+"",S,M,T,j,D,I,N,E,B,U,K;s=new qi({props:{kind:l[8],size:18}});function O(H,Z){return H[2]?pc:H[3]?mc:H[6]&&H[1]?dc:H[5]&&H[1]?uc:H[4]?fc:ac}let G=O(l),q=G(l);return{c(){e=u("div"),t=u("div"),n=u("header"),o=u("div"),nt(s.$$.fragment),r=b(),a=u("span"),d=F(f),p=b(),v=u("div"),g=F(k),y=F(" · "),S=F(w),M=b(),T=u("div"),j=u("button"),j.innerHTML='',D=b(),I=u("button"),I.innerHTML='',N=b(),E=u("div"),q.c(),i(a,"class","preview-name svelte-1cw3u0m"),i(a,"title",h=l[0].name),i(o,"class","preview-title svelte-1cw3u0m"),i(v,"class","preview-meta svelte-1cw3u0m"),i(j,"class","action-btn svelte-1cw3u0m"),i(j,"title",_("file.openExternal")),i(j,"aria-label",_("file.openExternal")),i(I,"class","action-btn action-btn-close svelte-1cw3u0m"),i(I,"title","Close"),i(I,"aria-label","Close preview"),i(T,"class","preview-actions svelte-1cw3u0m"),i(n,"class","preview-header svelte-1cw3u0m"),i(E,"class","preview-body svelte-1cw3u0m"),i(t,"class","modal svelte-1cw3u0m"),i(e,"class","overlay svelte-1cw3u0m"),i(e,"role","presentation")},m(H,Z){C(H,e,Z),c(e,t),c(t,n),c(n,o),et(s,o,null),c(o,r),c(o,a),c(a,d),c(n,p),c(n,v),c(v,g),c(v,y),c(v,S),c(n,M),c(n,T),c(T,j),c(T,D),c(T,I),c(t,N),c(t,E),q.m(E,null),B=!0,U||(K=[L(j,"click",l[9]),L(I,"click",l[10]),L(e,"click",gt(l[11])),L(e,"keydown",l[12])],U=!0)},p(H,[Z]){(!B||Z&1)&&f!==(f=H[0].name+"")&&W(d,f),(!B||Z&1&&h!==(h=H[0].name))&&i(a,"title",h),(!B||Z&1)&&k!==(k=Ht(H[0].size)+"")&&W(g,k),(!B||Z&1)&&w!==(w=Kl(H[0].mime)+"")&&W(S,w),G===(G=O(H))&&q?q.p(H,Z):(q.d(1),q=G(H),q&&(q.c(),q.m(E,null)))},i(H){B||(re(s.$$.fragment,H),B=!0)},o(H){fe(s.$$.fragment,H),B=!1},d(H){H&&z(e),tt(s),q.d(),U=!1,me(K)}}}function gc(l,e,t){let n,o,s,{item:r}=e,{content:a=""}=e,{loading:f=!1}=e,{error:d=""}=e;const h=Ut(),p=Ji(r);function v(S){S.key==="Escape"&&h("close")}function k(){h("openExternal",r.fileId)}Hi(()=>{window.addEventListener("keydown",v)}),cl(()=>{window.removeEventListener("keydown",v)});const g=()=>h("close"),y=()=>h("close"),w=S=>{S.key==="Escape"&&(S.preventDefault(),h("close"))};return l.$$set=S=>{"item"in S&&t(0,r=S.item),"content"in S&&t(1,a=S.content),"loading"in S&&t(2,f=S.loading),"error"in S&&t(3,d=S.error)},l.$$.update=()=>{l.$$.dirty&3&&t(6,n=Yi(r)&&a&&a.startsWith("data:")),l.$$.dirty&1&&t(5,o=Xi(r)||Qi(r)),l.$$.dirty&1&&t(4,s=Zi(r))},[r,a,f,d,s,o,n,h,p,k,g,y,w]}class bc extends _t{constructor(e){super(),pt(this,e,gc,hc,mt,{item:0,content:1,loading:2,error:3})}}function kc(l){let e,t,n,o,s,r,a,f,d,h,p,v,k,g,y,w,S;return{c(){e=u("div"),t=u("div"),n=u("h3"),o=F(l[0]),s=b(),r=u("p"),a=F(l[1]),f=b(),d=u("div"),h=u("button"),p=F(l[2]),k=b(),g=u("button"),y=F(l[3]),i(n,"class","svelte-1fv6yyk"),i(r,"class","message svelte-1fv6yyk"),i(h,"class",v="btn "+(l[4]?"btn-danger":"btn-primary")+" svelte-1fv6yyk"),i(g,"class","btn svelte-1fv6yyk"),i(d,"class","actions svelte-1fv6yyk"),i(t,"class","modal svelte-1fv6yyk"),i(e,"class","overlay svelte-1fv6yyk"),i(e,"role","presentation")},m(M,T){C(M,e,T),c(e,t),c(t,n),c(n,o),c(t,s),c(t,r),c(r,a),c(t,f),c(t,d),c(d,h),c(h,p),c(d,k),c(d,g),c(g,y),w||(S=[L(h,"click",l[6]),L(g,"click",l[7]),L(e,"click",gt(l[8])),L(e,"keydown",l[9])],w=!0)},p(M,[T]){T&1&&W(o,M[0]),T&2&&W(a,M[1]),T&4&&W(p,M[2]),T&16&&v!==(v="btn "+(M[4]?"btn-danger":"btn-primary")+" svelte-1fv6yyk")&&i(h,"class",v),T&8&&W(y,M[3])},i:ie,o:ie,d(M){M&&z(e),w=!1,me(S)}}}function yc(l,e,t){let{title:n=_("common.confirm")}=e,{message:o=""}=e,{confirmText:s=_("common.delete")}=e,{cancelText:r=_("common.cancel")}=e,{danger:a=!1}=e;const f=Ut(),d=()=>f("confirm"),h=()=>f("cancel"),p=()=>f("cancel"),v=k=>{k.key==="Escape"&&(k.preventDefault(),f("cancel"))};return l.$$set=k=>{"title"in k&&t(0,n=k.title),"message"in k&&t(1,o=k.message),"confirmText"in k&&t(2,s=k.confirmText),"cancelText"in k&&t(3,r=k.cancelText),"danger"in k&&t(4,a=k.danger)},[n,o,s,r,a,f,d,h,p,v]}class wc extends _t{constructor(e){super(),pt(this,e,yc,kc,mt,{title:0,message:1,confirmText:2,cancelText:3,danger:4})}}function zc(l){let e,t,n;return{c(){e=R("circle"),t=R("line"),n=R("line"),i(e,"cx","12"),i(e,"cy","12"),i(e,"r","10"),i(t,"x1","12"),i(t,"y1","16"),i(t,"x2","12"),i(t,"y2","12"),i(n,"x1","12"),i(n,"y1","8"),i(n,"x2","12.01"),i(n,"y2","8")},m(o,s){C(o,e,s),C(o,t,s),C(o,n,s)},d(o){o&&(z(e),z(t),z(n))}}}function Cc(l){let e,t,n,o;return{c(){e=R("rect"),t=R("polyline"),n=R("line"),o=R("line"),i(e,"x","3"),i(e,"y","5"),i(e,"width","18"),i(e,"height","14"),i(e,"rx","2"),i(t,"points","3 10 21 10"),i(n,"x1","8"),i(n,"y1","5"),i(n,"x2","8"),i(n,"y2","19"),i(o,"x1","16"),i(o,"y1","5"),i(o,"x2","16"),i(o,"y2","19")},m(s,r){C(s,e,r),C(s,t,r),C(s,n,r),C(s,o,r)},d(s){s&&(z(e),z(t),z(n),z(o))}}}function Sc(l){let e,t;return{c(){e=R("path"),t=R("polyline"),i(e,"d","M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"),i(t,"points","13 2 13 9 20 9")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function Tc(l){let e,t;return{c(){e=R("path"),t=R("path"),i(e,"d","M12 20h9"),i(t,"d","M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function jc(l){let e,t,n,o,s;return{c(){e=R("path"),t=R("path"),n=R("line"),o=R("line"),s=R("line"),i(e,"d","M4 19.5A2.5 2.5 0 0 1 6.5 17H20"),i(t,"d","M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"),i(n,"x1","8"),i(n,"y1","7"),i(n,"x2","16"),i(n,"y2","7"),i(o,"x1","8"),i(o,"y1","11"),i(o,"x2","14"),i(o,"y2","11"),i(s,"x1","8"),i(s,"y1","15"),i(s,"x2","12"),i(s,"y2","15")},m(r,a){C(r,e,a),C(r,t,a),C(r,n,a),C(r,o,a),C(r,s,a)},d(r){r&&(z(e),z(t),z(n),z(o),z(s))}}}function Nc(l){let e,t,n,o;return{c(){e=R("path"),t=R("polyline"),n=R("line"),o=R("line"),i(e,"d","M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"),i(t,"points","14 2 14 8 20 8"),i(n,"x1","16"),i(n,"y1","13"),i(n,"x2","8"),i(n,"y2","13"),i(o,"x1","16"),i(o,"y1","17"),i(o,"x2","8"),i(o,"y2","17")},m(s,r){C(s,e,r),C(s,t,r),C(s,n,r),C(s,o,r)},d(s){s&&(z(e),z(t),z(n),z(o))}}}function Mc(l){let e,t;return{c(){e=R("path"),t=R("circle"),i(e,"d","M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"),i(t,"cx","12"),i(t,"cy","7"),i(t,"r","4")},m(n,o){C(n,e,o),C(n,t,o)},d(n){n&&(z(e),z(t))}}}function Dc(l){let e,t,n,o;return{c(){e=R("rect"),t=R("rect"),n=R("rect"),o=R("rect"),i(e,"x","3"),i(e,"y","3"),i(e,"width","7"),i(e,"height","7"),i(e,"rx","1"),i(t,"x","14"),i(t,"y","3"),i(t,"width","7"),i(t,"height","4"),i(t,"rx","1"),i(n,"x","14"),i(n,"y","10"),i(n,"width","7"),i(n,"height","11"),i(n,"rx","1"),i(o,"x","3"),i(o,"y","14"),i(o,"width","7"),i(o,"height","7"),i(o,"rx","1")},m(s,r){C(s,e,r),C(s,t,r),C(s,n,r),C(s,o,r)},d(s){s&&(z(e),z(t),z(n),z(o))}}}function Ic(l){let e;return{c(){e=R("path"),i(e,"d","M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z")},m(t,n){C(t,e,n)},d(t){t&&z(e)}}}function Fc(l){let e;function t(s,r){return s[0]==="folder"?Ic:s[0]==="project"?Dc:s[0]==="client"?Mc:s[0]==="document"?Nc:s[0]==="recipe"?jc:s[0]==="note"?Tc:s[0]==="file"?Sc:s[0]==="case"?Cc:zc}let n=t(l),o=n(l);return{c(){e=R("svg"),o.c(),i(e,"width",l[1]),i(e,"height",l[1]),i(e,"viewBox","0 0 24 24"),i(e,"fill","none"),i(e,"stroke","currentColor"),i(e,"stroke-width","1.5"),i(e,"stroke-linecap","round"),i(e,"stroke-linejoin","round"),i(e,"xmlns","http://www.w3.org/2000/svg")},m(s,r){C(s,e,r),o.m(e,null)},p(s,[r]){n!==(n=t(s))&&(o.d(1),o=n(s),o&&(o.c(),o.m(e,null))),r&2&&i(e,"width",s[1]),r&2&&i(e,"height",s[1])},i:ie,o:ie,d(s){s&&z(e),o.d()}}}function Ec(l,e,t){let{kind:n="generic"}=e,{size:o=18}=e;return l.$$set=s=>{"kind"in s&&t(0,n=s.kind),"size"in s&&t(1,o=s.size)},[n,o]}class Wt extends _t{constructor(e){super(),pt(this,e,Ec,Fc,mt,{kind:0,size:1})}}function Yl(l,e,t){const n=l.slice();return n[44]=e[t],n}function Ac(l){let e;return{c(){e=u("span"),i(e,"class","tree-toggle-placeholder svelte-zj71cl")},m(t,n){C(t,e,n)},p:ie,d(t){t&&z(e)}}}function Lc(l){let e,t,n=l[1][l[44].id]?"▾":"▸",o,s,r;function a(){return l[25](l[44])}return{c(){e=u("button"),t=u("span"),o=F(n),i(t,"class","tree-arrow"),i(e,"class","tree-toggle svelte-zj71cl")},m(f,d){C(f,e,d),c(e,t),c(t,o),s||(r=L(e,"click",lt(a)),s=!0)},p(f,d){l=f,d[0]&3&&n!==(n=l[1][l[44].id]?"▾":"▸")&&W(o,n)},d(f){f&&z(e),s=!1,r()}}}function Xl(l){let e,t;return e=new $i({props:{nodes:l[44].children||[],expanded:l[1],selectedNodeId:l[2],level:l[3]+1,onSelect:l[4],onToggle:l[5],onContextMenu:l[6],onDrop:l[7]}}),{c(){nt(e.$$.fragment)},m(n,o){et(e,n,o),t=!0},p(n,o){const s={};o[0]&1&&(s.nodes=n[44].children||[]),o[0]&2&&(s.expanded=n[1]),o[0]&4&&(s.selectedNodeId=n[2]),o[0]&8&&(s.level=n[3]+1),o[0]&16&&(s.onSelect=n[4]),o[0]&32&&(s.onToggle=n[5]),o[0]&64&&(s.onContextMenu=n[6]),o[0]&128&&(s.onDrop=n[7]),e.$set(s)},i(n){t||(re(e.$$.fragment,n),t=!0)},o(n){fe(e.$$.fragment,n),t=!1},d(n){tt(e,n)}}}function Zl(l,e){let t,n,o,s,r,a,f,d=e[44].title+"",h,p,v=e[1][e[44].id]&&ol(e[44]),k,g,y,w;function S(J,X){return X[0]&1&&(n=null),n==null&&(n=!!Dt(J[44])),n?Lc:Ac}let M=S(e,[-1,-1]),T=M(e);r=new Wt({props:{kind:Ql(e[44]),size:16}});function j(...J){return e[26](e[44],...J)}function D(...J){return e[27](e[44],...J)}function I(){return e[28](e[44])}function N(...J){return e[29](e[44],...J)}function E(...J){return e[30](e[44],...J)}function B(...J){return e[31](e[44],...J)}function U(...J){return e[32](e[44],...J)}function K(...J){return e[33](e[44],...J)}function O(...J){return e[34](e[44],...J)}function G(...J){return e[35](e[44],...J)}function q(...J){return e[36](e[44],...J)}function H(...J){return e[37](e[44],...J)}let Z=v&&Xl(e);return{key:l,first:null,c(){t=u("div"),T.c(),o=b(),s=u("span"),nt(r.$$.fragment),a=b(),f=u("span"),h=F(d),p=b(),Z&&Z.c(),k=rt(),i(s,"class","tree-icon svelte-zj71cl"),i(s,"role","button"),i(s,"tabindex","-1"),i(f,"class","tree-label svelte-zj71cl"),i(f,"role","button"),i(f,"tabindex","-1"),i(t,"class","tree-item svelte-zj71cl"),He(t,"padding-left",e[3]*16+4+"px"),i(t,"draggable","true"),i(t,"role","button"),i(t,"tabindex","0"),we(t,"selected",e[2]===e[44].id),we(t,"drop-valid",e[8]===e[44].id&&e[9][e[44].id]),we(t,"drop-invalid",e[8]===e[44].id&&!e[9][e[44].id]),this.first=t},m(J,X){C(J,t,X),T.m(t,null),c(t,o),c(t,s),et(r,s,null),c(t,a),c(t,f),c(f,h),C(J,p,X),Z&&Z.m(J,X),C(J,k,X),g=!0,y||(w=[L(s,"click",j),L(s,"keydown",D),L(s,"dblclick",lt(e[24])),L(f,"click",lt(I)),L(f,"keydown",N),L(t,"dragstart",E),L(t,"dragover",B),L(t,"dragleave",U),L(t,"drop",K),L(t,"click",O),L(t,"keydown",G),L(t,"dblclick",q),L(t,"contextmenu",sl(H))],y=!0)},p(J,X){e=J,M===(M=S(e,X))&&T?T.p(e,X):(T.d(1),T=M(e),T&&(T.c(),T.m(t,o)));const Y={};X[0]&1&&(Y.kind=Ql(e[44])),r.$set(Y),(!g||X[0]&1)&&d!==(d=e[44].title+"")&&W(h,d),(!g||X[0]&8)&&He(t,"padding-left",e[3]*16+4+"px"),(!g||X[0]&5)&&we(t,"selected",e[2]===e[44].id),(!g||X[0]&769)&&we(t,"drop-valid",e[8]===e[44].id&&e[9][e[44].id]),(!g||X[0]&769)&&we(t,"drop-invalid",e[8]===e[44].id&&!e[9][e[44].id]),X[0]&3&&(v=e[1][e[44].id]&&ol(e[44])),v?Z?(Z.p(e,X),X[0]&3&&re(Z,1)):(Z=Xl(e),Z.c(),re(Z,1),Z.m(k.parentNode,k)):Z&&(Ye(),fe(Z,1,1,()=>{Z=null}),Xe())},i(J){g||(re(r.$$.fragment,J),re(Z),g=!0)},o(J){fe(r.$$.fragment,J),fe(Z),g=!1},d(J){J&&(z(t),z(p),z(k)),T.d(),tt(r),Z&&Z.d(J),y=!1,me(w)}}}function Pc(l){let e=[],t=new Map,n,o,s,r,a=ae(l[0]);const f=d=>d[44].id;for(let d=0;d0:l.has_children===!0}function xl(l){const e={};function t(n,o){for(const s of n)e[s.id]=o,s.children&&t(s.children,s.id)}return t(l,""),e}function $l(l){const e=[];function t(n){for(const o of n)e.push(o),o.children&&t(o.children)}return t(l),e}function Oc(l){try{return l.dataTransfer.getData("text/plain")}catch{return""}}function Rc(l,e,t){let n,o,s,{nodes:r=[]}=e,{expanded:a={}}=e,{selectedNodeId:f=""}=e,{level:d=0}=e,{onSelect:h=void 0}=e,{onToggle:p=void 0}=e,{onContextMenu:v=void 0}=e,{onDrop:k=void 0}=e,g={},y=null,w="",S="";const M=["folder","project","client","document","recipe","case"];cl(()=>{for(const V of Object.keys(g))clearTimeout(g[V]);y&&clearInterval(y)});function T(V){return M.includes(V.type)}function j(V,Q,de){if(!V||!Q||Q===V.id||!T(V))return!1;let ce=V.id;for(;ce;){if(ce===Q)return!1;ce=de[ce]||""}return!0}function D(V,Q){V.stopPropagation(),V.dataTransfer.effectAllowed="move",V.dataTransfer.setData("text/plain",Q.id),t(21,w=Q.id)}function I(V,Q){V.preventDefault(),V.stopPropagation(),V.dataTransfer.dropEffect="move",S!==Q.id&&t(8,S=Q.id),Dt(Q)&&!a[Q.id]&&!g[Q.id]&&(g[Q.id]=setTimeout(()=>{p&&p(Q.id),delete g[Q.id]},600));const de=V.currentTarget.closest(".workspace-tree-area");if(de){const ce=de.getBoundingClientRect(),ue=30;V.clientY-ce.top{de.scrollTop-=10},50)):ce.bottom-V.clientY{de.scrollTop+=10},50)):y&&(clearInterval(y),y=null)}}function N(V,Q){const de=V.relatedTarget;de&&V.currentTarget.contains(de)||(S===Q.id&&t(8,S=""),g[Q.id]&&(clearTimeout(g[Q.id]),delete g[Q.id]),y&&(clearInterval(y),y=null))}function E(V,Q){V.preventDefault(),V.stopPropagation(),g[Q.id]&&(clearTimeout(g[Q.id]),delete g[Q.id]),y&&(clearInterval(y),y=null);const de=$l(r),ce=xl(de),ue=Oc(V);if(!j(Q,ue,ce)){t(8,S=""),t(21,w="");return}k&&k(ue,Q.id),t(8,S=""),t(21,w="")}function B(){t(8,S=""),t(21,w="");for(const V of Object.keys(g))clearTimeout(g[V]),delete g[V];y&&(clearInterval(y),y=null)}function U(V,Q){V.target.closest(".tree-toggle")||V.target.closest(".tree-icon")||h&&h(Q)}function K(V,Q){Dt(Q)&&p&&p(Q.id)}function O(V,Q){(V.key==="Enter"||V.key===" ")&&(V.preventDefault(),h&&h(Q))}function G(V,Q){V.stopPropagation(),Dt(Q)&&p&&p(Q.id)}function q(V,Q){(V.key==="Enter"||V.key===" ")&&(V.preventDefault(),V.stopPropagation(),Dt(Q)&&p&&p(Q.id))}function H(V,Q){(V.key==="Enter"||V.key===" ")&&(V.preventDefault(),h&&h(Q))}function Z(V,Q,de){const ce={};function ue(he){for(const Ke of he)ce[Ke.id]=j(Ke,Q,de),Ke.children&&ue(Ke.children)}return ue(V),ce}function J(V){Ui.call(this,l,V)}const X=V=>p&&p(V.id),Y=(V,Q)=>G(Q,V),P=(V,Q)=>q(Q,V),ee=V=>h&&h(V),ve=(V,Q)=>H(Q,V),te=(V,Q)=>D(Q,V),le=(V,Q)=>I(Q,V),oe=(V,Q)=>N(Q,V),_e=(V,Q)=>E(Q,V),Me=(V,Q)=>U(Q,V),Ie=(V,Q)=>O(Q,V),Ze=(V,Q)=>K(Q,V),Re=(V,Q)=>v&&v(Q,V);return l.$$set=V=>{"nodes"in V&&t(0,r=V.nodes),"expanded"in V&&t(1,a=V.expanded),"selectedNodeId"in V&&t(2,f=V.selectedNodeId),"level"in V&&t(3,d=V.level),"onSelect"in V&&t(4,h=V.onSelect),"onToggle"in V&&t(5,p=V.onToggle),"onContextMenu"in V&&t(6,v=V.onContextMenu),"onDrop"in V&&t(7,k=V.onDrop)},l.$$.update=()=>{l.$$.dirty[0]&1&&t(23,n=$l(r)),l.$$.dirty[0]&8388608&&t(22,o=xl(n)),l.$$.dirty[0]&14680064&&t(9,s=Z(n,w,o))},[r,a,f,d,h,p,v,k,S,s,D,I,N,E,B,U,K,O,G,q,H,w,o,n,J,X,Y,P,ee,ve,te,le,oe,_e,Me,Ie,Ze,Re]}class $i extends _t{constructor(e){super(),pt(this,e,Rc,Pc,mt,{nodes:0,expanded:1,selectedNodeId:2,level:3,onSelect:4,onToggle:5,onContextMenu:6,onDrop:7},null,[-1,-1])}}function en(l,e,t){const n=l.slice();return n[252]=e[t],n}function tn(l,e,t){const n=l.slice();return n[255]=e[t],n}function ln(l,e,t){const n=l.slice();return n[255]=e[t],n}function nn(l,e,t){const n=l.slice();return n[279]=e[t],n}function on(l,e,t){const n=l.slice();return n[279]=e[t],n}function sn(l,e,t){const n=l.slice();return n[297]=e[t],n}function rn(l,e,t){const n=l.slice();return n[279]=e[t],n}function cn(l,e,t){const n=l.slice();return n[276]=e[t],n[302]=e,n[303]=t,n}function an(l,e,t){const n=l.slice();return n[285]=e[t],n}function fn(l,e,t){const n=l.slice();return n[288]=e[t],n}function un(l,e,t){const n=l.slice();return n[288]=e[t],n}function dn(l,e,t){const n=l.slice();return n[276]=e[t],n[293]=e,n[294]=t,n}function mn(l,e,t){const n=l.slice();return n[279]=e[t],n}function pn(l,e,t){const n=l.slice();return n[260]=e[t],n}function _n(l,e,t){const n=l.slice();return n[276]=e[t],n}function vn(l,e,t){const n=l.slice();return n[271]=e[t],n}function hn(l,e,t){const n=l.slice();return n[268]=e[t],n}function gn(l,e,t){const n=l.slice();return n[263]=e[t],n}function bn(l,e,t){const n=l.slice();return n[260]=e[t],n}function kn(l,e,t){const n=l.slice();return n[263]=e[t],n}function yn(l,e,t){const n=l.slice();return n[282]=e[t],n}function wn(l,e,t){const n=l.slice();return n[306]=e[t],n}function zn(l,e,t){const n=l.slice();return n[309]=e[t],n}function Cn(l){let e,t;return{c(){e=u("span"),t=F(l[23]),i(e,"class","nav-badge svelte-44iz1r")},m(n,o){C(n,e,o),c(e,t)},p(n,o){o[0]&8388608&&W(t,n[23])},d(n){n&&z(e)}}}function Sn(l){let e,t=l[309].label+"",n,o,s,r,a,f,d=l[309].id==="journal"&&l[23]>0&&Cn(l);function h(){return l[143](l[309])}return{c(){e=u("button"),n=F(t),o=b(),d&&d.c(),s=b(),i(e,"class",r="nav-item "+(l[13]===l[309].id?"selected":"")+" svelte-44iz1r")},m(p,v){C(p,e,v),c(e,n),c(e,o),d&&d.m(e,null),c(e,s),a||(f=L(e,"click",h),a=!0)},p(p,v){l=p,v[0]&1&&t!==(t=l[309].label+"")&&W(n,t),l[309].id==="journal"&&l[23]>0?d?d.p(l,v):(d=Cn(l),d.c(),d.m(e,s)):d&&(d.d(1),d=null),v[0]&8193&&r!==(r="nav-item "+(l[13]===l[309].id?"selected":"")+" svelte-44iz1r")&&i(e,"class",r)},d(p){p&&z(e),d&&d.d(),a=!1,f()}}}function Bc(l){let e;return{c(){e=u("div"),e.textContent=`${_("nav.noNodes")}`,i(e,"class","nav-empty svelte-44iz1r")},m(t,n){C(t,e,n)},p:ie,i:ie,o:ie,d(t){t&&z(e)}}}function Vc(l){var r;let e,t,n,o,s;return t=new $i({props:{nodes:l[1],expanded:l[39],selectedNodeId:((r=l[14])==null?void 0:r.id)||"",onSelect:l[70],onToggle:l[100],onContextMenu:l[98],onDrop:l[101]}}),{c(){e=u("div"),nt(t.$$.fragment),i(e,"class","workspace-tree-area svelte-44iz1r"),i(e,"role","region"),i(e,"aria-label",_("nav.workspace")),we(e,"drop-valid",l[50])},m(a,f){C(a,e,f),et(t,e,null),n=!0,o||(s=[L(e,"dragover",sl(l[103])),L(e,"dragleave",l[104]),L(e,"drop",l[102])],o=!0)},p(a,f){var h;const d={};f[0]&2&&(d.nodes=a[1]),f[1]&256&&(d.expanded=a[39]),f[0]&16384&&(d.selectedNodeId=((h=a[14])==null?void 0:h.id)||""),t.$set(d),(!n||f[1]&524288)&&we(e,"drop-valid",a[50])},i(a){n||(re(t.$$.fragment,a),n=!0)},o(a){fe(t.$$.fragment,a),n=!1},d(a){a&&z(e),tt(t),o=!1,me(s)}}}function Hc(l){let e;return{c(){e=u("span"),e.textContent=`${_("nav.selectPrompt")}`,i(e,"class","crumb placeholder svelte-44iz1r")},m(t,n){C(t,e,n)},p:ie,d(t){t&&z(e)}}}function Uc(l){let e,t=ae(l[0]),n=[];for(let o=0;o0&&Nn(l);return{c(){e=u("button"),t=R("svg"),n=R("polyline"),o=R("polyline"),s=R("path"),r=b(),d&&d.c(),i(n,"points","23 4 23 10 17 10"),i(n,"class","svelte-44iz1r"),i(o,"points","1 20 1 14 7 14"),i(o,"class","svelte-44iz1r"),i(s,"d","M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"),i(s,"class","svelte-44iz1r"),i(t,"width","16"),i(t,"height","16"),i(t,"viewBox","0 0 24 24"),i(t,"fill","none"),i(t,"stroke","currentColor"),i(t,"stroke-width","2"),i(t,"stroke-linecap","round"),i(t,"stroke-linejoin","round"),i(t,"class","svelte-44iz1r"),i(e,"class","header-sync-btn svelte-44iz1r"),e.disabled=l[61],i(e,"title",_("nav.syncNow"))},m(h,p){C(h,e,p),c(e,t),c(t,n),c(t,o),c(t,s),c(e,r),d&&d.m(e,null),a||(f=L(e,"click",l[141]),a=!0)},p(h,p){h[60].unpushedOps>0?d?d.p(h,p):(d=Nn(h),d.c(),d.m(e,null)):d&&(d.d(1),d=null),p[1]&1073741824&&(e.disabled=h[61])},d(h){h&&z(e),d&&d.d(),a=!1,f()}}}function Nn(l){let e,t=l[60].unpushedOps+"",n;return{c(){e=u("span"),n=F(t),i(e,"class","sync-badge svelte-44iz1r")},m(o,s){C(o,e,s),c(e,n)},p(o,s){s[1]&536870912&&t!==(t=o[60].unpushedOps+"")&&W(n,t)},d(o){o&&z(e)}}}function Mn(l){let e,t,n,o,s,r;return{c(){e=u("div"),t=F(l[12]),n=b(),o=u("button"),o.innerHTML='',i(o,"class","dismiss-btn svelte-44iz1r"),i(o,"aria-label","Dismiss"),i(e,"class","error-banner svelte-44iz1r"),i(e,"role","button"),i(e,"tabindex","0")},m(a,f){C(a,e,f),c(e,t),c(e,n),c(e,o),s||(r=[L(o,"click",lt(l[144])),L(e,"click",l[145]),L(e,"keydown",function(){At(st(l[146]))&&st(l[146]).apply(this,arguments)})],s=!0)},p(a,f){l=a,f[0]&4096&&W(t,l[12])},d(a){a&&z(e),s=!1,me(r)}}}function Kc(l){let e,t,n;function o(a,f){if(a[35])return xc;if(a[0].length>0)return Qc;if(a[12])return Zc}let s=o(l),r=s&&s(l);return{c(){e=u("div"),t=u("h2"),t.textContent=`${_("welcome.title")}`,n=b(),r&&r.c(),i(t,"class","svelte-44iz1r"),i(e,"class","welcome svelte-44iz1r")},m(a,f){C(a,e,f),c(e,t),c(e,n),r&&r.m(e,null)},p(a,f){s===(s=o(a))&&r?r.p(a,f):(r&&r.d(1),r=s&&s(a),r&&(r.c(),r.m(e,null)))},i:ie,o:ie,d(a){a&&z(e),r&&r.d()}}}function Gc(l){let e,t,n,o;function s(f,d){return f[4].length===0?ea:$c}let r=s(l),a=r(l);return{c(){e=u("div"),t=u("div"),n=u("h2"),n.textContent=`${_("activity.title")}`,o=b(),a.c(),i(n,"class","svelte-44iz1r"),i(t,"class","activity-feed-header svelte-44iz1r"),i(e,"class","activity-feed svelte-44iz1r")},m(f,d){C(f,e,d),c(e,t),c(t,n),c(e,o),a.m(e,null)},p(f,d){r===(r=s(f))&&a?a.p(f,d):(a.d(1),a=r(f),a&&(a.c(),a.m(e,null)))},i:ie,o:ie,d(f){f&&z(e),a.d()}}}function qc(l){let e,t,n,o,s,r=l[3].date+"",a,f,d,h,p=l[3].summary&&Fn(l),v=l[22].length>0&&Pn(l);function k(w,S){return w[3].groups&&w[3].groups.length>0?la:ta}let g=k(l),y=g(l);return{c(){e=u("div"),t=u("div"),n=u("h2"),n.textContent=`${_("today.title")}`,o=b(),s=u("span"),a=F(r),f=b(),p&&p.c(),d=b(),v&&v.c(),h=b(),y.c(),i(n,"class","svelte-44iz1r"),i(s,"class","today-date svelte-44iz1r"),i(t,"class","today-header svelte-44iz1r"),i(e,"class","today-dashboard svelte-44iz1r")},m(w,S){C(w,e,S),c(e,t),c(t,n),c(t,o),c(t,s),c(s,a),c(e,f),p&&p.m(e,null),c(e,d),v&&v.m(e,null),c(e,h),y.m(e,null)},p(w,S){S[0]&8&&r!==(r=w[3].date+"")&&W(a,r),w[3].summary?p?p.p(w,S):(p=Fn(w),p.c(),p.m(e,d)):p&&(p.d(1),p=null),w[22].length>0?v?v.p(w,S):(v=Pn(w),v.c(),v.m(e,h)):v&&(v.d(1),v=null),g===(g=k(w))&&y?y.p(w,S):(y.d(1),y=g(w),y&&(y.c(),y.m(e,null)))},i:ie,o:ie,d(w){w&&z(e),p&&p.d(),v&&v.d(),y.d()}}}function Jc(l){let e,t,n,o,s,r,a,f,d,h,p,v,k,g,y,w,S,M,T,j,D,I,N,E,B,U,K,O,G,q,H=l[22].length>0&&Kn(l),Z=l[6]&&qn(l);function J(P,ee){return P[5].length===0?sa:oa}let X=J(l),Y=X(l);return{c(){e=u("div"),t=u("div"),n=u("h2"),n.textContent=`${_("journal.title")}`,o=b(),s=u("div"),r=u("label"),a=u("span"),a.textContent=`${_("journal.dateFrom")}`,f=b(),d=u("input"),h=b(),p=u("label"),v=u("span"),v.textContent=`${_("journal.dateTo")}`,k=b(),g=u("input"),y=b(),w=u("label"),S=u("input"),M=b(),T=u("span"),T.textContent=`${_("journal.includeChildren")}`,j=b(),D=u("button"),D.textContent=`${_("journal.filter")}`,I=b(),N=u("button"),N.textContent=`${_("journal.exportCSV")}`,E=b(),B=u("button"),B.textContent=`${_("journal.exportMarkdown")}`,U=b(),H&&H.c(),K=b(),Z&&Z.c(),O=b(),Y.c(),i(n,"class","svelte-44iz1r"),i(a,"class","label-text svelte-44iz1r"),i(d,"type","date"),i(d,"class","svelte-44iz1r"),i(r,"class","svelte-44iz1r"),i(v,"class","label-text svelte-44iz1r"),i(g,"type","date"),i(g,"class","svelte-44iz1r"),i(p,"class","svelte-44iz1r"),i(S,"type","checkbox"),i(S,"class","svelte-44iz1r"),i(T,"class","svelte-44iz1r"),i(w,"class","checkbox-label svelte-44iz1r"),i(D,"class","btn btn-sm svelte-44iz1r"),i(N,"class","btn btn-sm svelte-44iz1r"),i(B,"class","btn btn-sm svelte-44iz1r"),i(s,"class","journal-filters svelte-44iz1r"),i(t,"class","journal-header svelte-44iz1r"),i(e,"class","journal-screen svelte-44iz1r")},m(P,ee){C(P,e,ee),c(e,t),c(t,n),c(t,o),c(t,s),c(s,r),c(r,a),c(r,f),c(r,d),Ce(d,l[7]),c(s,h),c(s,p),c(p,v),c(p,k),c(p,g),Ce(g,l[8]),c(s,y),c(s,w),c(w,S),S.checked=l[9],c(w,M),c(w,T),c(s,j),c(s,D),c(s,I),c(s,N),c(s,E),c(s,B),c(e,U),H&&H.m(e,null),c(e,K),Z&&Z.m(e,null),c(e,O),Y.m(e,null),G||(q=[L(d,"input",l[178]),L(g,"input",l[179]),L(S,"change",l[180]),L(D,"click",l[119]),L(N,"click",l[120]),L(B,"click",l[121])],G=!0)},p(P,ee){ee[0]&128&&Ce(d,P[7]),ee[0]&256&&Ce(g,P[8]),ee[0]&512&&(S.checked=P[9]),P[22].length>0?H?H.p(P,ee):(H=Kn(P),H.c(),H.m(e,K)):H&&(H.d(1),H=null),P[6]?Z?Z.p(P,ee):(Z=qn(P),Z.c(),Z.m(e,O)):Z&&(Z.d(1),Z=null),X===(X=J(P))&&Y?Y.p(P,ee):(Y.d(1),Y=X(P),Y&&(Y.c(),Y.m(e,null)))},i:ie,o:ie,d(P){P&&z(e),H&&H.d(),Z&&Z.d(),Y.d(),G=!1,me(q)}}}function Yc(l){let e,t,n,o,s,r,a=ae(l[68]),f=[];for(let v=0;v{h[g]=null}),Xe()),~o?(s=h[o],s?s.p(v,k):(s=h[o]=d[o](v),s.c()),re(s,1),s.m(n,null)):s=null)},i(v){r||(re(s),r=!0)},o(v){fe(s),r=!1},d(v){v&&(z(e),z(t),z(n)),Le(f,v),~o&&h[o].d()}}}function Xc(l){let e,t,n,o=l[17].title+"",s,r,a,f,d,h,p,v,k,g,y,w=l[17].dirty&&hi();return{c(){e=u("div"),t=u("div"),n=u("span"),s=F(o),r=b(),w&&w.c(),a=b(),f=u("div"),d=u("button"),d.textContent=`${_("common.save")}`,h=b(),p=u("button"),p.textContent=`${_("common.close")}`,v=b(),k=u("textarea"),i(n,"class","note-title svelte-44iz1r"),i(d,"class","btn btn-primary svelte-44iz1r"),i(p,"class","btn svelte-44iz1r"),i(f,"class","note-editor-actions svelte-44iz1r"),i(t,"class","note-editor-header svelte-44iz1r"),i(k,"class","note-textarea svelte-44iz1r"),i(k,"placeholder",_("note.placeholder")),i(e,"class","note-editor svelte-44iz1r")},m(S,M){C(S,e,M),c(e,t),c(t,n),c(n,s),c(t,r),w&&w.m(t,null),c(t,a),c(t,f),c(f,d),c(f,h),c(f,p),c(e,v),c(e,k),Ce(k,l[17].content),g||(y=[L(d,"click",l[115]),L(p,"click",l[113]),L(k,"input",l[147]),L(k,"input",l[114])],g=!0)},p(S,M){M[0]&131072&&o!==(o=S[17].title+"")&&W(s,o),S[17].dirty?w||(w=hi(),w.c(),w.m(t,a)):w&&(w.d(1),w=null),M[0]&131072&&Ce(k,S[17].content)},i:ie,o:ie,d(S){S&&z(e),w&&w.d(),g=!1,me(y)}}}function Zc(l){let e,t=_("common.error")+"",n,o,s;return{c(){e=u("p"),n=F(t),o=b(),s=F(l[12]),i(e,"class","error-text svelte-44iz1r")},m(r,a){C(r,e,a),c(e,n),c(e,o),c(e,s)},p(r,a){a[0]&4096&&W(s,r[12])},d(r){r&&z(e)}}}function Qc(l){let e,t,n;return{c(){e=u("p"),e.textContent=`${_("welcome.selectSection")}`,t=b(),n=u("p"),n.textContent=`${_("welcome.createCase")}`,i(e,"class","svelte-44iz1r"),i(n,"class","hint svelte-44iz1r")},m(o,s){C(o,e,s),C(o,t,s),C(o,n,s)},p:ie,d(o){o&&(z(e),z(t),z(n))}}}function xc(l){let e;return{c(){e=u("p"),e.textContent=`${_("common.loading")}`,i(e,"class","svelte-44iz1r")},m(t,n){C(t,e,n)},p:ie,d(t){t&&z(e)}}}function $c(l){let e,t=ae(l[4]),n=[];for(let o=0;o0&&En(l),s=l[3].summary.notes>0&&An(l),r=l[3].summary.files>0&&Ln(l);return{c(){e=u("div"),o&&o.c(),t=b(),s&&s.c(),n=b(),r&&r.c(),i(e,"class","today-summary svelte-44iz1r")},m(a,f){C(a,e,f),o&&o.m(e,null),c(e,t),s&&s.m(e,null),c(e,n),r&&r.m(e,null)},p(a,f){a[3].summary.changedCases>0?o?o.p(a,f):(o=En(a),o.c(),o.m(e,t)):o&&(o.d(1),o=null),a[3].summary.notes>0?s?s.p(a,f):(s=An(a),s.c(),s.m(e,n)):s&&(s.d(1),s=null),a[3].summary.files>0?r?r.p(a,f):(r=Ln(a),r.c(),r.m(e,null)):r&&(r.d(1),r=null)},d(a){a&&z(e),o&&o.d(),s&&s.d(),r&&r.d()}}}function En(l){let e,t=l[3].summary.changedCases+"",n,o,s=dt(l[3].summary.changedCases,_("today.plural.case_one"),_("today.plural.case_few"),_("today.plural.case_many"))+"",r;return{c(){e=u("span"),n=F(t),o=b(),r=F(s),i(e,"class","summary-chip svelte-44iz1r")},m(a,f){C(a,e,f),c(e,n),c(e,o),c(e,r)},p(a,f){f[0]&8&&t!==(t=a[3].summary.changedCases+"")&&W(n,t),f[0]&8&&s!==(s=dt(a[3].summary.changedCases,_("today.plural.case_one"),_("today.plural.case_few"),_("today.plural.case_many"))+"")&&W(r,s)},d(a){a&&z(e)}}}function An(l){let e,t=l[3].summary.notes+"",n,o,s=dt(l[3].summary.notes,_("today.plural.note_one"),_("today.plural.note_few"),_("today.plural.note_many"))+"",r;return{c(){e=u("span"),n=F(t),o=b(),r=F(s),i(e,"class","summary-chip svelte-44iz1r")},m(a,f){C(a,e,f),c(e,n),c(e,o),c(e,r)},p(a,f){f[0]&8&&t!==(t=a[3].summary.notes+"")&&W(n,t),f[0]&8&&s!==(s=dt(a[3].summary.notes,_("today.plural.note_one"),_("today.plural.note_few"),_("today.plural.note_many"))+"")&&W(r,s)},d(a){a&&z(e)}}}function Ln(l){let e,t=l[3].summary.files+"",n,o,s=dt(l[3].summary.files,_("today.plural.file_one"),_("today.plural.file_few"),_("today.plural.file_many"))+"",r;return{c(){e=u("span"),n=F(t),o=b(),r=F(s),i(e,"class","summary-chip svelte-44iz1r")},m(a,f){C(a,e,f),c(e,n),c(e,o),c(e,r)},p(a,f){f[0]&8&&t!==(t=a[3].summary.files+"")&&W(n,t),f[0]&8&&s!==(s=dt(a[3].summary.files,_("today.plural.file_one"),_("today.plural.file_few"),_("today.plural.file_many"))+"")&&W(r,s)},d(a){a&&z(e)}}}function Pn(l){let e,t,n,o=ae(l[22]),s=[];for(let r=0;r0&&Un(l);return{c(){for(let r=0;r0?s?s.p(r,a):(s=Un(r),s.c(),s.m(t.parentNode,t)):s&&(s.d(1),s=null)},d(r){r&&(z(e),z(t)),Le(o,r),s&&s.d(r)}}}function Rn(l){let e,t=l[297].events.length+"",n,o,s=dt(l[297].events.length,_("today.plural.event_one"),_("today.plural.event_few"),_("today.plural.event_many"))+"",r;return{c(){e=u("span"),n=F(t),o=b(),r=F(s),i(e,"class","today-case-count svelte-44iz1r")},m(a,f){C(a,e,f),c(e,n),c(e,o),c(e,r)},p(a,f){f[0]&8&&t!==(t=a[297].events.length+"")&&W(n,t),f[0]&8&&s!==(s=dt(a[297].events.length,_("today.plural.event_one"),_("today.plural.event_few"),_("today.plural.event_many"))+"")&&W(r,s)},d(a){a&&z(e)}}}function na(l){let e;return{c(){e=u("div"),e.textContent=`${_("today.changedCases")}`,i(e,"class","today-events-empty svelte-44iz1r")},m(t,n){C(t,e,n)},p:ie,d(t){t&&z(e)}}}function ia(l){let e,t=ae(l[297].events),n=[];for(let o=0;o0?ia:na}let I=D(l),N=I(l);return{c(){e=u("div"),t=u("div"),n=u("span"),s=F(o),r=b(),a=u("span"),d=F(f),h=b(),M&&M.c(),p=b(),v=u("span"),g=F(k),y=b(),N.c(),i(n,"class","today-case-title svelte-44iz1r"),i(a,"class","today-case-type svelte-44iz1r"),i(v,"class","today-case-time svelte-44iz1r"),i(t,"class","today-case-header svelte-44iz1r"),i(t,"role","button"),i(t,"tabindex","0"),i(e,"class","today-case svelte-44iz1r")},m(E,B){C(E,e,B),c(e,t),c(t,n),c(n,s),c(t,r),c(t,a),c(a,d),c(t,h),M&&M.m(t,null),c(t,p),c(t,v),c(v,g),c(e,y),N.m(e,null),w||(S=[L(t,"click",T),L(t,"keydown",j)],w=!0)},p(E,B){l=E,B[0]&8&&o!==(o=l[297].nodeTitle+"")&&W(s,o),B[0]&8&&f!==(f=l[128](l[297].nodeKind)+"")&&W(d,f),l[297].events?M?M.p(l,B):(M=Rn(l),M.c(),M.m(t,p)):M&&(M.d(1),M=null),B[0]&8&&k!==(k=ct(l[297].lastActivityAt)+"")&&W(g,k),I===(I=D(l))&&N?N.p(l,B):(N.d(1),N=I(l),N&&(N.c(),N.m(e,null)))},d(E){E&&z(e),M&&M.d(),N.d(),w=!1,me(S)}}}function Un(l){let e,t,n,o=ae(l[3].events),s=[];for(let r=0;r0&&Jn(l),D=l[6].byNode&&l[6].byNode.length>0&&Xn(l);return{c(){e=u("div"),t=u("div"),o=F(n),s=F(": "),a=F(r),f=F("ч "),h=F(d),p=F("м ("),k=F(v),g=b(),w=F(y),S=F(")"),M=b(),j&&j.c(),T=b(),D&&D.c(),i(t,"class","summary-total svelte-44iz1r"),i(e,"class","journal-summary svelte-44iz1r")},m(I,N){C(I,e,N),c(e,t),c(t,o),c(t,s),c(t,a),c(t,f),c(t,h),c(t,p),c(t,k),c(t,g),c(t,w),c(t,S),c(e,M),j&&j.m(e,null),c(e,T),D&&D.m(e,null)},p(I,N){N[0]&64&&r!==(r=Math.floor(I[6].totalMinutes/60)+"")&&W(a,r),N[0]&64&&d!==(d=I[6].totalMinutes%60+"")&&W(h,d),N[0]&64&&v!==(v=I[6].totalEntries+"")&&W(k,v),I[6].byDay&&I[6].byDay.length>0?j?j.p(I,N):(j=Jn(I),j.c(),j.m(e,T)):j&&(j.d(1),j=null),I[6].byNode&&I[6].byNode.length>0?D?D.p(I,N):(D=Xn(I),D.c(),D.m(e,null)):D&&(D.d(1),D=null)},d(I){I&&z(e),j&&j.d(),D&&D.d()}}}function Jn(l){let e,t,n,o=ae(l[6].byDay),s=[];for(let r=0;r0,k,g,y,w=v&&ni(l);function S(j,D){return j[19].length===0?va:_a}let M=S(l),T=M(l);return{c(){e=u("div"),t=u("div"),n=u("input"),o=b(),s=u("input"),r=b(),a=u("button"),d=F(f),p=b(),w&&w.c(),k=b(),T.c(),i(n,"type","text"),i(n,"placeholder",_("worklog.whatDone")),i(n,"class","svelte-44iz1r"),i(s,"type","number"),i(s,"placeholder",_("worklog.minutes")),i(s,"min","1"),i(s,"class","svelte-44iz1r"),i(a,"class","btn btn-primary svelte-44iz1r"),a.disabled=h=!l[21].trim()||!l[20],i(t,"class","worklog-form svelte-44iz1r"),i(e,"class","worklog-tab svelte-44iz1r")},m(j,D){C(j,e,D),c(e,t),c(t,n),Ce(n,l[21]),c(t,o),c(t,s),Ce(s,l[20]),c(t,r),c(t,a),c(a,d),c(e,p),w&&w.m(e,null),c(e,k),T.m(e,null),g||(y=[L(n,"input",l[174]),L(s,"input",l[175]),L(a,"click",l[116])],g=!0)},p(j,D){D[0]&2097152&&n.value!==j[21]&&Ce(n,j[21]),D[0]&1048576&&Bt(s.value)!==j[20]&&Ce(s,j[20]),D[0]&3145728&&h!==(h=!j[21].trim()||!j[20])&&(a.disabled=h),D[0]&4210688&&(v=j[14]&&j[22].filter(j[142]).length>0),v?w?w.p(j,D):(w=ni(j),w.c(),w.m(e,k)):w&&(w.d(1),w=null),M===(M=S(j))&&T?T.p(j,D):(T.d(1),T=M(j),T&&(T.c(),T.m(e,null)))},i:ie,o:ie,d(j){j&&z(e),w&&w.d(),T.d(),g=!1,me(y)}}}function aa(l){let e,t,n,o,s,r;function a(h,p){return h[18].length===0?ga:ha}let f=a(l),d=f(l);return{c(){e=u("div"),t=u("div"),n=u("button"),n.textContent=`${_("action.addAction")}`,o=b(),d.c(),i(n,"class","btn btn-primary svelte-44iz1r"),i(t,"class","tab-toolbar svelte-44iz1r"),i(e,"class","actions-tab svelte-44iz1r")},m(h,p){C(h,e,p),c(e,t),c(t,n),c(e,o),d.m(e,null),s||(r=L(n,"click",l[129]),s=!0)},p(h,p){f===(f=a(h))&&d?d.p(h,p):(d.d(1),d=f(h),d&&(d.c(),d.m(e,null)))},i:ie,o:ie,d(h){h&&z(e),d.d(),s=!1,r()}}}function fa(l){let e,t,n,o=_("file.addFile")+"",s,r,a,f=_("file.addFolder")+"",d,h,p,v,k,g,y,w,S,M,T,j,D,I=l[48].items.length>0&&ri(l);const N=[ka,ba],E=[];function B(O,G){return O[40]?0:1}g=B(l),y=E[g]=N[g](l);let U=l[36]&&!l[38]&&ai(),K=l[44]&&fi(l);return{c(){e=u("div"),t=u("div"),n=u("button"),s=F(o),r=b(),a=u("button"),d=F(f),h=b(),p=u("button"),p.textContent=`${_("file.newFile")}`,v=b(),I&&I.c(),k=b(),y.c(),w=b(),U&&U.c(),S=b(),K&&K.c(),M=rt(),i(n,"class","btn btn-primary svelte-44iz1r"),n.disabled=l[36],i(a,"class","btn svelte-44iz1r"),a.disabled=l[36],i(p,"class","btn svelte-44iz1r"),i(t,"class","tab-toolbar svelte-44iz1r"),i(e,"class","files-tab svelte-44iz1r")},m(O,G){C(O,e,G),c(e,t),c(t,n),c(n,s),c(t,r),c(t,a),c(a,d),c(t,h),c(t,p),c(t,v),I&&I.m(t,null),c(e,k),E[g].m(e,null),c(e,w),U&&U.m(e,null),C(O,S,G),K&&K.m(O,G),C(O,M,G),T=!0,j||(D=[L(n,"click",l[122]),L(a,"click",l[123]),L(p,"click",l[77])],j=!0)},p(O,G){(!T||G[1]&32)&&(n.disabled=O[36]),(!T||G[1]&32)&&(a.disabled=O[36]),O[48].items.length>0?I?I.p(O,G):(I=ri(O),I.c(),I.m(t,null)):I&&(I.d(1),I=null);let q=g;g=B(O),g===q?E[g].p(O,G):(Ye(),fe(E[q],1,1,()=>{E[q]=null}),Xe(),y=E[g],y?y.p(O,G):(y=E[g]=N[g](O),y.c()),re(y,1),y.m(e,w)),O[36]&&!O[38]?U||(U=ai(),U.c(),U.m(e,null)):U&&(U.d(1),U=null),O[44]?K?(K.p(O,G),G[1]&8192&&re(K,1)):(K=fi(O),K.c(),re(K,1),K.m(M.parentNode,M)):K&&(Ye(),fe(K,1,1,()=>{K=null}),Xe())},i(O){T||(re(y),re(K),T=!0)},o(O){fe(y),fe(K),T=!1},d(O){O&&(z(e),z(S),z(M)),I&&I.d(),E[g].d(),U&&U.d(),K&&K.d(O),j=!1,me(D)}}}function ua(l){let e,t,n,o,s,r,a,f=l[29]&&ui(l);function d(v,k){return v[16].length===0&&!v[29]?Ta:Sa}let h=d(l),p=h(l);return{c(){e=u("div"),t=u("div"),n=u("button"),n.textContent=`${_("note.add")}`,o=b(),f&&f.c(),s=b(),p.c(),i(n,"class","btn btn-primary svelte-44iz1r"),i(t,"class","tab-toolbar svelte-44iz1r"),i(e,"class","notes-tab svelte-44iz1r")},m(v,k){C(v,e,k),c(e,t),c(t,n),c(e,o),f&&f.m(e,null),c(e,s),p.m(e,null),r||(a=L(n,"click",l[109]),r=!0)},p(v,k){v[29]?f?f.p(v,k):(f=ui(v),f.c(),f.m(e,s)):f&&(f.d(1),f=null),h===(h=d(v))&&p?p.p(v,k):(p.d(1),p=h(v),p&&(p.c(),p.m(e,null)))},i:ie,o:ie,d(v){v&&z(e),f&&f.d(),p.d(),r=!1,a()}}}function da(l){let e,t,n=l[14].title+"",o,s,r,a,f,d,h=l[128](l[14].type)+"",p,v,k,g,y,w=(l[14].section||"—")+"",S,M,T,j,D,I=at(l[14].createdAt)+"",N,E,B,U,K,O,G,q,H=_("overview.newNote")+"",Z,J,X,Y,P,ee,ve=_("overview.addFile")+"",te,le,oe,_e,Me,Ie,Ze=_("overview.addAction")+"",Re,V,Q,de,ce,ue,he,Ke=_("overview.logTime")+"",Qe,qe,ge,ye,se,Se=l[16].length>0&&mi(l),Fe=l[19].length>0&&_i(l);return{c(){e=u("div"),t=u("h2"),o=F(n),s=b(),r=u("div"),a=u("div"),f=u("span"),f.textContent=`${_("overview.type")}`,d=u("span"),p=F(h),v=b(),k=u("div"),g=u("span"),g.textContent=`${_("overview.section")}`,y=u("span"),S=F(w),M=b(),T=u("div"),j=u("span"),j.textContent=`${_("overview.created")}`,D=u("span"),N=F(I),E=b(),B=u("div"),U=u("button"),K=R("svg"),O=R("path"),G=R("path"),q=b(),Z=F(H),J=b(),X=u("button"),Y=R("svg"),P=R("path"),ee=b(),te=F(ve),le=b(),oe=u("button"),_e=R("svg"),Me=R("polygon"),Ie=b(),Re=F(Ze),V=b(),Q=u("button"),de=R("svg"),ce=R("circle"),ue=R("polyline"),he=b(),Qe=F(Ke),qe=b(),Se&&Se.c(),ge=b(),Fe&&Fe.c(),i(t,"class","svelte-44iz1r"),i(f,"class","meta-label svelte-44iz1r"),i(d,"class","svelte-44iz1r"),i(a,"class","meta-item svelte-44iz1r"),i(g,"class","meta-label svelte-44iz1r"),i(y,"class","svelte-44iz1r"),i(k,"class","meta-item svelte-44iz1r"),i(j,"class","meta-label svelte-44iz1r"),i(D,"class","svelte-44iz1r"),i(T,"class","meta-item svelte-44iz1r"),i(r,"class","meta-grid svelte-44iz1r"),i(O,"d","M12 20h9"),i(O,"class","svelte-44iz1r"),i(G,"d","M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"),i(G,"class","svelte-44iz1r"),i(K,"width","16"),i(K,"height","16"),i(K,"viewBox","0 0 24 24"),i(K,"fill","none"),i(K,"stroke","currentColor"),i(K,"stroke-width","2"),i(K,"stroke-linecap","round"),i(K,"stroke-linejoin","round"),i(K,"class","svelte-44iz1r"),i(U,"class","qa-btn svelte-44iz1r"),i(P,"d","M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"),i(P,"class","svelte-44iz1r"),i(Y,"width","16"),i(Y,"height","16"),i(Y,"viewBox","0 0 24 24"),i(Y,"fill","none"),i(Y,"stroke","currentColor"),i(Y,"stroke-width","2"),i(Y,"stroke-linecap","round"),i(Y,"stroke-linejoin","round"),i(Y,"class","svelte-44iz1r"),i(X,"class","qa-btn svelte-44iz1r"),i(Me,"points","13 2 3 14 12 14 11 22 21 10 12 10 13 2"),i(Me,"class","svelte-44iz1r"),i(_e,"width","16"),i(_e,"height","16"),i(_e,"viewBox","0 0 24 24"),i(_e,"fill","none"),i(_e,"stroke","currentColor"),i(_e,"stroke-width","2"),i(_e,"stroke-linecap","round"),i(_e,"stroke-linejoin","round"),i(_e,"class","svelte-44iz1r"),i(oe,"class","qa-btn svelte-44iz1r"),i(ce,"cx","12"),i(ce,"cy","12"),i(ce,"r","10"),i(ce,"class","svelte-44iz1r"),i(ue,"points","12 6 12 12 16 14"),i(ue,"class","svelte-44iz1r"),i(de,"width","16"),i(de,"height","16"),i(de,"viewBox","0 0 24 24"),i(de,"fill","none"),i(de,"stroke","currentColor"),i(de,"stroke-width","2"),i(de,"stroke-linecap","round"),i(de,"stroke-linejoin","round"),i(de,"class","svelte-44iz1r"),i(Q,"class","qa-btn svelte-44iz1r"),i(B,"class","quick-actions svelte-44iz1r"),i(e,"class","overview svelte-44iz1r")},m(Ne,De){C(Ne,e,De),c(e,t),c(t,o),c(e,s),c(e,r),c(r,a),c(a,f),c(a,d),c(d,p),c(r,v),c(r,k),c(k,g),c(k,y),c(y,S),c(r,M),c(r,T),c(T,j),c(T,D),c(D,N),c(e,E),c(e,B),c(B,U),c(U,K),c(K,O),c(K,G),c(U,q),c(U,Z),c(B,J),c(B,X),c(X,Y),c(Y,P),c(X,ee),c(X,te),c(B,le),c(B,oe),c(oe,_e),c(_e,Me),c(oe,Ie),c(oe,Re),c(B,V),c(B,Q),c(Q,de),c(de,ce),c(de,ue),c(Q,he),c(Q,Qe),c(e,qe),Se&&Se.m(e,null),c(e,ge),Fe&&Fe.m(e,null),ye||(se=[L(U,"click",l[149]),L(X,"click",l[150]),L(oe,"click",l[129]),L(Q,"click",l[151])],ye=!0)},p(Ne,De){De[0]&16384&&n!==(n=Ne[14].title+"")&&W(o,n),De[0]&16384&&h!==(h=Ne[128](Ne[14].type)+"")&&W(p,h),De[0]&16384&&w!==(w=(Ne[14].section||"—")+"")&&W(S,w),De[0]&16384&&I!==(I=at(Ne[14].createdAt)+"")&&W(N,I),Ne[16].length>0?Se?Se.p(Ne,De):(Se=mi(Ne),Se.c(),Se.m(e,ge)):Se&&(Se.d(1),Se=null),Ne[19].length>0?Fe?Fe.p(Ne,De):(Fe=_i(Ne),Fe.c(),Fe.m(e,null)):Fe&&(Fe.d(1),Fe=null)},i:ie,o:ie,d(Ne){Ne&&z(e),Se&&Se.d(),Fe&&Fe.d(),ye=!1,me(se)}}}function ma(l){let e,t=ae(l[10]),n=[];for(let o=0;o',T=b(),i(n,"class","action-title svelte-44iz1r"),i(a,"class","action-type svelte-44iz1r"),i(p,"class","action-data svelte-44iz1r"),i(t,"class","action-info svelte-44iz1r"),i(w,"class","btn btn-sm svelte-44iz1r"),i(M,"class","btn btn-sm btn-danger svelte-44iz1r"),i(y,"class","action-btns svelte-44iz1r"),i(e,"class","action-card svelte-44iz1r")},m(E,B){C(E,e,B),c(e,t),c(t,n),c(n,s),c(t,r),c(t,a),c(a,d),c(t,h),c(t,p),c(p,k),c(e,g),c(e,y),c(y,w),c(y,S),c(y,M),c(e,T),j||(D=[L(w,"click",I),L(M,"click",N)],j=!0)},p(E,B){l=E,B[0]&262144&&o!==(o=l[271].title+"")&&W(s,o),B[0]&262144&&f!==(f=l[133](l[271].type)+"")&&W(d,f),B[0]&262144&&v!==(v=l[271].data+"")&&W(k,v)},d(E){E&&z(e),j=!1,me(D)}}}function ri(l){let e,t=_("common.paste")+"",n,o,s=l[48].items.length+"",r,a,f;return{c(){e=u("button"),n=F(t),o=b(),r=F(s),i(e,"class","btn svelte-44iz1r")},m(d,h){C(d,e,h),c(e,n),c(e,o),c(e,r),a||(f=L(e,"click",l[82]),a=!0)},p(d,h){h[1]&131072&&s!==(s=d[48].items.length+"")&&W(r,s)},d(d){d&&z(e),a=!1,f()}}}function ba(l){let e,t,n,o,s,r,a;const f=[wa,ya],d=[];function h(g,y){return g[42].length>0?0:1}e=h(l),t=d[e]=f[e](l);const p=[Ca,za],v=[];function k(g,y){return g[43].length===0?0:1}return o=k(l),s=v[o]=p[o](l),{c(){t.c(),n=b(),s.c(),r=rt()},m(g,y){d[e].m(g,y),C(g,n,y),v[o].m(g,y),C(g,r,y),a=!0},p(g,y){let w=e;e=h(g),e===w?d[e].p(g,y):(Ye(),fe(d[w],1,1,()=>{d[w]=null}),Xe(),t=d[e],t?t.p(g,y):(t=d[e]=f[e](g),t.c()),re(t,1),t.m(n.parentNode,n));let S=o;o=k(g),o===S?v[o].p(g,y):(Ye(),fe(v[S],1,1,()=>{v[S]=null}),Xe(),s=v[o],s?s.p(g,y):(s=v[o]=p[o](g),s.c()),re(s,1),s.m(r.parentNode,r))},i(g){a||(re(t),re(s),a=!0)},o(g){fe(t),fe(s),a=!1},d(g){g&&(z(n),z(r)),d[e].d(g),v[o].d(g)}}}function ka(l){let e,t;return{c(){e=u("div"),t=u("p"),t.textContent=`${_("common.loading")}`,i(t,"class","svelte-44iz1r"),i(e,"class","empty-state svelte-44iz1r")},m(n,o){C(n,e,o),c(e,t)},p:ie,i:ie,o:ie,d(n){n&&z(e)}}}function ya(l){let e,t;return e=new xi({props:{crumbs:[{name:_("file.root")}]}}),{c(){nt(e.$$.fragment)},m(n,o){et(e,n,o),t=!0},p:ie,i(n){t||(re(e.$$.fragment,n),t=!0)},o(n){fe(e.$$.fragment,n),t=!1},d(n){tt(e,n)}}}function wa(l){let e,t,n,o,s,r,a,f=_("common.back")+"",d,h,p,v;return e=new xi({props:{crumbs:[{name:_("file.root")},...l[42]]}}),e.$on("navigate",l[158]),{c(){nt(e.$$.fragment),t=b(),n=u("button"),o=R("svg"),s=R("line"),r=R("polyline"),a=b(),d=F(f),i(s,"x1","19"),i(s,"y1","12"),i(s,"x2","5"),i(s,"y2","12"),i(s,"class","svelte-44iz1r"),i(r,"points","12 19 5 12 12 5"),i(r,"class","svelte-44iz1r"),i(o,"width","14"),i(o,"height","14"),i(o,"viewBox","0 0 24 24"),i(o,"fill","none"),i(o,"stroke","currentColor"),i(o,"stroke-width","2"),i(o,"stroke-linecap","round"),i(o,"stroke-linejoin","round"),i(o,"class","svelte-44iz1r"),i(n,"class","btn btn-sm back-btn svelte-44iz1r")},m(k,g){et(e,k,g),C(k,t,g),C(k,n,g),c(n,o),c(o,s),c(o,r),c(n,a),c(n,d),h=!0,p||(v=L(n,"click",l[73]),p=!0)},p(k,g){const y={};g[1]&2048&&(y.crumbs=[{name:_("file.root")},...k[42]]),e.$set(y)},i(k){h||(re(e.$$.fragment,k),h=!0)},o(k){fe(e.$$.fragment,k),h=!1},d(k){k&&(z(t),z(n)),tt(e,k),p=!1,v()}}}function za(l){let e,t=[],n=new Map,o,s=ae(l[43]);const r=a=>a[268].id;for(let a=0;a0?_("file.noFiles"):_("file.noFilesCase"))+"",r,a,f,d,h,p,v,k,g,y;return{c(){e=u("div"),t=u("div"),t.innerHTML='',n=b(),o=u("p"),r=F(s),a=b(),f=u("p"),f.textContent=`${_("file.hint")}`,d=b(),h=u("div"),p=u("button"),p.textContent=`${_("file.addFileSimple")}`,v=b(),k=u("button"),k.textContent=`${_("file.addFolderSimple")}`,i(t,"class","empty-icon svelte-44iz1r"),i(o,"class","svelte-44iz1r"),i(f,"class","hint svelte-44iz1r"),i(p,"class","btn btn-primary svelte-44iz1r"),i(k,"class","btn svelte-44iz1r"),i(h,"class","empty-actions svelte-44iz1r"),i(e,"class","empty-state svelte-44iz1r")},m(w,S){C(w,e,S),c(e,t),c(e,n),c(e,o),c(o,r),c(e,a),c(e,f),c(e,d),c(e,h),c(h,p),c(h,v),c(h,k),g||(y=[L(p,"click",l[122]),L(k,"click",l[123])],g=!0)},p(w,S){S[1]&2048&&s!==(s=(w[42].length>0?_("file.noFiles"):_("file.noFilesCase"))+"")&&W(r,s)},i:ie,o:ie,d(w){w&&z(e),g=!1,me(y)}}}function ci(l,e){let t,n,o;return n=new nc({props:{item:e[268],selected:e[49].includes(e[268].id),onDragStart:e[86],onDragOver:e[87],onDrop:e[88]}}),n.$on("navigate",e[159]),n.$on("preview",e[160]),n.$on("openExternal",e[161]),n.$on("showInFolder",e[162]),n.$on("delete",e[163]),n.$on("rename",e[164]),n.$on("duplicate",e[165]),n.$on("cut",e[166]),n.$on("copy",e[167]),n.$on("selectOne",e[168]),n.$on("toggleSelect",e[169]),n.$on("rangeSelect",e[170]),{key:l,first:null,c(){t=rt(),nt(n.$$.fragment),this.first=t},m(s,r){C(s,t,r),et(n,s,r),o=!0},p(s,r){e=s;const a={};r[1]&4096&&(a.item=e[268]),r[1]&266240&&(a.selected=e[49].includes(e[268].id)),n.$set(a)},i(s){o||(re(n.$$.fragment,s),o=!0)},o(s){fe(n.$$.fragment,s),o=!1},d(s){s&&z(t),tt(n,s)}}}function ai(l){let e,t;return{c(){e=u("div"),t=u("p"),t.textContent=`${_("file.scanning")}`,i(t,"class","svelte-44iz1r"),i(e,"class","empty-state svelte-44iz1r")},m(n,o){C(n,e,o),c(e,t)},d(n){n&&z(e)}}}function fi(l){let e,t;return e=new bc({props:{item:l[44],content:l[45],loading:l[46],error:l[47]}}),e.$on("close",l[76]),e.$on("openExternal",l[171]),{c(){nt(e.$$.fragment)},m(n,o){et(e,n,o),t=!0},p(n,o){const s={};o[1]&8192&&(s.item=n[44]),o[1]&16384&&(s.content=n[45]),o[1]&32768&&(s.loading=n[46]),o[1]&65536&&(s.error=n[47]),e.$set(s)},i(n){t||(re(e.$$.fragment,n),t=!0)},o(n){fe(e.$$.fragment,n),t=!1},d(n){tt(e,n)}}}function ui(l){let e,t,n,o,s,r,a,f,d;return{c(){e=u("div"),t=u("input"),n=b(),o=u("div"),s=u("button"),s.textContent=`${_("common.create")}`,r=b(),a=u("button"),a.textContent=`${_("common.cancel")}`,i(t,"type","text"),i(t,"placeholder",_("note.title")),i(t,"class","svelte-44iz1r"),i(s,"class","btn btn-primary svelte-44iz1r"),i(a,"class","btn svelte-44iz1r"),i(o,"class","form-actions svelte-44iz1r"),i(e,"class","create-form svelte-44iz1r")},m(h,p){C(h,e,p),c(e,t),Ce(t,l[30]),c(e,n),c(e,o),c(o,s),c(o,r),c(o,a),f||(d=[L(t,"input",l[154]),L(t,"keydown",l[155]),L(s,"click",l[111]),L(a,"click",l[110])],f=!0)},p(h,p){p[0]&1073741824&&t.value!==h[30]&&Ce(t,h[30])},d(h){h&&z(e),f=!1,me(d)}}}function Sa(l){let e,t=ae(l[16]),n=[];for(let o=0;ofe(ee[te],1,1,()=>{ee[te]=null});return{c(){e=u("div"),t=u("div"),n=u("h3"),n.textContent=`${_("nav.createNode")}`,o=b(),Y&&Y.c(),s=b(),r=u("div"),a=u("span"),a.textContent=`${_("template.select")}`,f=b(),d=u("div"),h=u("button"),nt(p.$$.fragment),v=b(),k=u("div"),g=u("span"),g.textContent=`${_("template.optionNone")}`,y=b(),w=u("span"),w.textContent=`${_("template.none.desc")}`,S=b();for(let te=0;te{g=null}),Xe()),w[28].node&&w[28].node.parent_id?y?y.p(w,S):(y=Ci(w),y.c(),y.m(t,s)):y&&(y.d(1),y=null),(!p||S[0]&268435456)&&He(t,"left",w[28].x+"px"),(!p||S[0]&268435456)&&He(t,"top",w[28].y+"px")},i(w){p||(re(g),p=!0)},o(w){fe(g),p=!1},d(w){w&&z(e),g&&g.d(),y&&y.d(),v=!1,me(k)}}}function wi(l){let e,t,n,o,s,r=ae(l[2].length>0?l[2]:[{id:"",title:"template.optionNone",icon:"folder"}]),a=[];for(let d=0;dfe(a[d],1,1,()=>{a[d]=null});return{c(){e=u("div"),e.textContent=`${_("common.create")}`,t=b();for(let d=0;d0?d[2]:[{id:"",title:"template.optionNone",icon:"folder"}]);let p;for(p=0;pl[207].call(y)),i(v,"class","svelte-44iz1r"),i(p,"class","form-group svelte-44iz1r"),i(T,"class","label-text svelte-44iz1r"),i(N,"type","text"),i(N,"placeholder",E=l[33]==="open_url"?_("action.urlPlaceholder"):l[33]==="open_folder"||l[33]==="open_file"?_("action.pathPlaceholder"):_("action.commandPlaceholder")),i(N,"class","svelte-44iz1r"),i(M,"class","svelte-44iz1r"),i(S,"class","form-group svelte-44iz1r"),i(K,"class","btn btn-primary svelte-44iz1r"),i(G,"class","btn svelte-44iz1r"),i(U,"class","modal-actions svelte-44iz1r"),i(t,"class","modal svelte-44iz1r"),i(e,"class","modal-overlay svelte-44iz1r"),i(e,"role","button"),i(e,"tabindex","0")},m(X,Y){C(X,e,Y),c(e,t),c(t,n),c(t,o),c(t,s),c(s,r),c(r,a),c(r,f),c(r,d),Ce(d,l[32]),c(t,h),c(t,p),c(p,v),c(v,k),c(v,g),c(v,y);for(let P=0;P0?0:1}T=Se(l),j=se[T]=ye[T](l);function Fe(x,pe){return x[14]?Wc:x[13]?Uc:Hc}let Ne=Fe(l),De=Ne(l),Ue=((Ge=l[60])==null?void 0:Ge.configured)&&jn(l),Be=l[12]&&Mn(l);const ut=[Xc,Yc,Jc,qc,Gc,Kc],Pe=[];function We(x,pe){return x[17]?0:x[14]?1:x[13]==="journal"?2:x[13]==="today"&&x[3]?3:x[13]==="activity"?4:5}Me=We(l),Ie=Pe[Me]=ut[Me](l);let Te=l[24]&&gi(l),je=l[28].visible&&yi(l),Ee=l[31]&&Si(l),Ae=l[38]&&l[37]&&ji(l),Oe=l[56]&&Mi(l),be=l[51]&&Ii(l),ze=l[59]&&Fi(l);return{c(){var x;e=u("div"),t=u("aside"),n=u("div"),o=u("span"),o.textContent="⚒",s=b(),r=u("span"),r.textContent=`${_("nav.brand")}`,a=b(),f=u("nav"),d=u("div"),h=u("div"),h.textContent=`${_("nav.system")}`,p=b();for(let pe=0;pe{se[Je]=null}),Xe(),j=se[T],j?j.p(x,pe):(j=se[T]=ye[T](x),j.c()),re(j,1),j.m(k,null)),(!he||pe[1]&536870912)&&we(G,"active",(Lt=x[60])==null?void 0:Lt.configured),(!he||pe[0]&2048)&&W(X,x[11]),Ne===(Ne=Fe(x))&&De?De.p(x,pe):(De.d(1),De=Ne(x),De&&(De.c(),De.m(ve,null))),(bt=x[60])!=null&&bt.configured?Ue?Ue.p(x,pe):(Ue=jn(x),Ue.c(),Ue.m(le,null)):Ue&&(Ue.d(1),Ue=null),x[12]?Be?Be.p(x,pe):(Be=Mn(x),Be.c(),Be.m(P,_e)):Be&&(Be.d(1),Be=null);let Ve=Me;Me=We(x),Me===Ve?Pe[Me].p(x,pe):(Ye(),fe(Pe[Ve],1,1,()=>{Pe[Ve]=null}),Xe(),Ie=Pe[Me],Ie?Ie.p(x,pe):(Ie=Pe[Me]=ut[Me](x),Ie.c()),re(Ie,1),Ie.m(P,Ze)),x[24]?Te?(Te.p(x,pe),pe[0]&16777216&&re(Te,1)):(Te=gi(x),Te.c(),re(Te,1),Te.m(P,Re)):Te&&(Ye(),fe(Te,1,1,()=>{Te=null}),Xe()),x[28].visible?je?(je.p(x,pe),pe[0]&268435456&&re(je,1)):(je=yi(x),je.c(),re(je,1),je.m(P,V)):je&&(Ye(),fe(je,1,1,()=>{je=null}),Xe()),x[31]?Ee?Ee.p(x,pe):(Ee=Si(x),Ee.c(),Ee.m(P,Q)):Ee&&(Ee.d(1),Ee=null),x[38]&&x[37]?Ae?Ae.p(x,pe):(Ae=ji(x),Ae.c(),Ae.m(P,de)):Ae&&(Ae.d(1),Ae=null),x[56]?Oe?Oe.p(x,pe):(Oe=Mi(x),Oe.c(),Oe.m(P,ce)):Oe&&(Oe.d(1),Oe=null),x[51]?be?(be.p(x,pe),pe[1]&1048576&&re(be,1)):(be=Ii(x),be.c(),re(be,1),be.m(P,ue)):be&&(Ye(),fe(be,1,1,()=>{be=null}),Xe()),x[59]?ze?ze.p(x,pe):(ze=Fi(x),ze.c(),ze.m(P,null)):ze&&(ze.d(1),ze=null)},i(x){he||(re(j),re(Ie),re(Te),re(je),re(be),he=!0)},o(x){fe(j),fe(Ie),fe(Te),fe(je),fe(be),he=!1},d(x){x&&z(e),Le(ge,x),se[T].d(),De.d(),Ue&&Ue.d(),Be&&Be.d(),Pe[Me].d(),Te&&Te.d(),je&&je.d(),Ee&&Ee.d(),Ae&&Ae.d(),Oe&&Oe.d(),be&&be.d(),ze&&ze.d(),Ke=!1,me(Qe)}}}function $(l,...e){try{if(window.go&&window.go.main&&window.go.main.App){const t=window.go.main.App[l];if(typeof t=="function")return t(...e)}}catch(t){console.error("Wails call error:",l,t)}return Promise.reject(new Error("Wails not connected: "+l))}function It(l,e,t){for(const n of l){if(n.id===e)return n.children=t,n.has_children=t.length>0,!0;if(n.children&&It(n.children,e,t))return!0}return!1}function eo(l,e,t){for(const n of l){if(n.id===e)return n.children=t,n.has_children=t.length>0,!0;if(n.children&&eo(n.children,e,t))return!0}return!1}function Bi(l,e,t){const n=new Blob([e],{type:t}),o=URL.createObjectURL(n),s=document.createElement("a");s.href=o,s.download=l,document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(o)}function Ct(l){return l==="note_created"||l==="file_added"||l==="folder_added"||l==="node_created"?"+":l==="file_deleted"||l==="folder_deleted"?"×":l==="file_renamed"||l==="folder_renamed"||l==="note_updated"||l==="node_updated"?"~":l==="file_copied"?"⧉":l==="file_moved"?"→":"•"}function ct(l){if(!l)return"";try{return new Date(l).toLocaleTimeString("ru-RU",{hour:"2-digit",minute:"2-digit"})}catch{return""}}function at(l){if(!l)return"";try{return new Date(l).toLocaleDateString("ru-RU",{day:"numeric",month:"short"})}catch{return l}}function dt(l,e,t,n){return l=Math.abs(l)%100,l>=5&&l<=20?n:(l%=10,l===1?e:l>=2&&l<=4?t:n)}function st(l){return e=>{(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),l())}}function Aa(l,e,t){let n=[],o=[],s=[],r=null,a=[],f=0,d=!0,h=[],p=null,v="",k="",g=!1,y=[],w="",S="",M="",T=null,j="overview",D=[],I=null,N=[],E=[],B=[],U="",K="",O=[],G=0,q=!1,H="",Z=null,J=null,X={visible:!1,x:0,y:0,node:null},Y=!1,P="",ee=!1,ve="",te="open_url",le="",oe=[{id:"open_url",label:_("action.openUrl")},{id:"open_file",label:_("action.openFile")},{id:"open_folder",label:_("action.openFolder")},{id:"run_command",label:_("action.runCommand")},{id:"run_script",label:_("action.runScript")},{id:"open_terminal",label:_("action.openTerminal")},{id:"launch_app",label:_("action.launchApp")}],_e=!0,Me=!1,Ie=null,Ze=!1,Re="",V="",Q={},de=!1,ce=null,ue=[],he=[],Ke=null,Qe="",qe=!1,ge="",ye={items:[],mode:"copy"},se=[],Se=[],Fe=!1,Ne=!1,De="",Ue="",Be=!1,ut=_("common.delete"),Pe=null,We=null,Te=!1,je="",Ee="",Ae="",Oe=!1,be=null,ze=!1,Ge="",x="",pe="",Je=0,Ve="";const Lt=[{id:"overview",label:_("tab.overview")},{id:"notes",label:_("tab.notes")},{id:"files",label:_("tab.files")},{id:"actions",label:_("tab.actions")},{id:"worklog",label:_("tab.worklog")},{id:"activity",label:_("tab.activity")}];let bt=null;Hi(async()=>{try{t(11,w=await $("VerstakVersion")||"verstak-gui/v2"),t(0,n=await $("ListSystemViews")||[]),t(1,o=await $("ListWorkspaceTree")||[]),t(2,s=await $("ListEnabledTemplates")||[])}catch(m){t(12,S=String(m)),t(0,n=[{id:"today",label:_("nav.today")},{id:"inbox",label:_("nav.inbox")},{id:"activity",label:_("nav.activity")}]),t(1,o=[]),t(2,s=[])}window.runtime&&window.runtime.EventsOn&&(window.runtime.EventsOn("files-dropped",Ao),bt=()=>window.runtime.EventsOff("files-dropped")),window.addEventListener("keydown",kl),t(35,_e=!1),Nt()}),cl(()=>{bt&&bt(),window.removeEventListener("keydown",kl)});async function xe(m){t(13,M=m),t(14,T=null),t(15,j="overview"),t(16,D=[]),N=[],t(18,E=[]),t(19,B=[]),t(22,O=[]),t(24,q=!1),t(12,S=""),t(3,r=null),t(4,a=[]),f=0,d=!0,t(5,h=[]),t(6,p=null);try{m==="today"?(t(3,r=await $("ListTodayView")||{cases:[]}),t(22,O=await $("GetSuggestions")||[]),t(23,G=O.length)):m==="journal"?await Qt():m==="activity"&&(t(4,a=await $("ListActivityFeed",50,0)||[]),f=a.length,d=a.length===50)}catch(A){t(12,S=String(A)),t(3,r={cases:[]}),t(4,a=[])}}async function ft(m){t(14,T=m),t(15,j="overview"),t(16,D=[]),N=[],t(18,E=[]),t(19,B=[]),t(22,O=[]),t(43,he=[]),t(42,ue=[]),t(41,ce=null),t(44,Ke=null),t(45,Qe=""),t(49,se=[]),Se=[],t(17,I=null),t(24,q=!1),t(29,Y=!1),t(12,S=""),t(10,y=[]),await al(m.id)}async function al(m){try{t(16,D=await $("ListNotes",m)||[])}catch{}try{N=await $("ListFiles",m)||[]}catch{}try{t(18,E=await $("ListActions",m)||[])}catch{}try{t(19,B=await $("ListWorklog",m)||[])}catch{}try{t(22,O=await $("GetSuggestions")||[]),t(23,G=O.length)}catch{t(22,O=[]),t(23,G=0)}try{t(10,y=await $("ListActivityByNode",m,50,0)||[])}catch{}}async function $e(m){t(40,de=!0);try{let A=await $("ListItems",m)||[];A.sort((ne,ke)=>ne.type!==ke.type?ne.type==="folder"?-1:1:(ne.name||"").localeCompare(ke.name||"")),t(43,he=A)}catch{t(43,he=[])}t(40,de=!1)}async function Kt(m){if(!T)return;try{const ne=await $("GetNodeDetail",m);ne&&t(42,ue=[...ue,{id:m,name:ne.title}])}catch{t(42,ue=[...ue,{id:m,name:"..."}])}t(41,ce=m),t(39,Q={...Q,[m]:!0});const A=await $("ListWorkspaceChildren",m)||[];It(o,m,A),t(1,o=[...o]),await $e(m)}function fl(){if(ue.length<2)t(42,ue=[]),t(41,ce=null),$e(T.id);else{const m=ue[ue.length-2];t(42,ue=ue.slice(0,-1)),t(41,ce=m.id),$e(m.id)}}function ul(m){const A=ue[m];t(42,ue=ue.slice(0,m+1)),t(41,ce=A.id),$e(A.id)}async function Gt(m){t(44,Ke=m),t(45,Qe=""),t(47,ge=""),t(46,qe=!0);try{Xr(m)?t(45,Qe=await $("GetFileBase64",m.fileId)||""):Zr(m)&&t(45,Qe=await $("ReadFileText",m.fileId)||"")}catch(A){t(47,ge=String(A))}t(46,qe=!1)}function qt(){t(44,Ke=null),t(45,Qe=""),t(47,ge="")}async function to(){const m=prompt(_("file.namePrompt"));if(!(!m||!m.trim()))try{const A=ce||T.id;await $("CreateEmptyFile",A,m.trim()),await $e(A),await Xt(A)}catch(A){t(12,S=String(A))}}async function dl(m){try{await $("DuplicateNode",m);const A=ce||T.id;await $e(A),await Xt(A)}catch(A){t(12,S=String(A))}}function ml(m){const A=he.find(ne=>ne.id===m);A&&Yt(A.id,A.name)}function pl(m){t(48,ye={items:[m],mode:"cut"})}function _l(m){t(48,ye={items:[m],mode:"copy"})}async function vl(){if(ye.items.length===0)return;const m=ce||T.id;try{if(ye.mode==="copy")for(const A of ye.items)await $("DuplicateNode",A);else for(const A of ye.items)await $("MoveNode",A,m);t(48,ye={items:[],mode:"copy"}),await $e(m)}catch(A){t(12,S=String(A))}}function hl(m){se.includes(m)?t(49,se=se.filter(A=>A!==m)):t(49,se=[...se,m])}function gl(m){t(49,se=[m])}function lo(){t(49,se=he.map(m=>m.id))}function bl(m){if(he.length===0)return;const A=se.length>0?se[se.length-1]:he[0].id,ne=he.findIndex(vt=>vt.id===A),ke=he.findIndex(vt=>vt.id===m);if(ne===-1||ke===-1)return;const ot=Math.min(ne,ke),Mt=Math.max(ne,ke),pr=he.slice(ot,Mt+1).map(vt=>vt.id),Ol=new Set(se);pr.forEach(vt=>Ol.add(vt)),t(49,se=[...Ol])}function no(){t(49,se=[])}function Jt(m){return m.length>0?m:he.map(A=>A.id)}async function io(){const m=Jt(se),A=he.find(ke=>ke.id===m[0]);let ne;m.length===1&&(A==null?void 0:A.type)==="folder"?ne=_("delete.folder"):m.length===1?ne=_("delete.file"):ne=_("delete.files",{count:m.length}),St({title:_("delete.confirmTitle"),message:_("delete.confirmMessage")+" "+ne+"?",confirmText:_("common.delete"),danger:!0,onConfirm:async()=>{for(const ot of m)try{await $("DeleteFileOrFolder",ot)}catch(Mt){t(12,S=String(Mt))}t(49,se=[]);const ke=ce||T.id;await $e(ke)}})}function oo(){const m=Jt(se);t(48,ye={items:m,mode:"cut"}),t(49,se=[])}function so(){const m=Jt(se);t(48,ye={items:m,mode:"copy"}),t(49,se=[])}function ro(m,A){const ne=se.includes(A)?se:[A];Se=ne,m.dataTransfer.effectAllowed="move",m.dataTransfer.setData("text/plain",ne.join(","))}function co(m,A){const ne=he.find(ke=>ke.id===A);ne&&ne.type==="folder"&&(m.preventDefault(),m.dataTransfer.dropEffect="move")}async function ao(m,A){if(m.preventDefault(),Se.length!==0){for(const ne of Se)try{await $("MoveNode",ne,A)}catch(ke){t(12,S=String(ke))}Se=[],t(49,se=[]),await $e(ce||T.id)}}function kl(m){if(j==="files"&&!(m.target.tagName==="INPUT"||m.target.tagName==="TEXTAREA"))if(m.ctrlKey||m.metaKey)m.key==="c"||m.key==="C"?(m.preventDefault(),so()):m.key==="x"||m.key==="X"?(m.preventDefault(),oo()):m.key==="v"||m.key==="V"?(m.preventDefault(),vl()):m.key==="a"||m.key==="A"?(m.preventDefault(),lo()):m.key==="o"||m.key==="O"?(m.preventDefault(),fo()):m.key==="Enter"&&(m.preventDefault(),yl());else if(m.key==="Enter")m.preventDefault(),yl();else if(m.key==="Delete"||m.key==="Backspace"){if(Ke){m.preventDefault(),qt();return}if(se.length>0){m.preventDefault(),io();return}if(m.key==="Backspace"&&ue.length>0){m.preventDefault(),fl();return}}else if(m.key==="Escape"){if(Ke){qt();return}if(se.length>0){no();return}}else m.key==="F2"&&(m.preventDefault(),uo())}function yl(){if(se.length===1){const m=he.find(A=>A.id===se[0]);m&&(m.type==="folder"?Kt(m.id):Gt(m))}}function fo(){if(se.length===1){const m=he.find(A=>A.id===se[0]);m&&m.fileId&&$("OpenFile",m.fileId)}}function Yt(m,A){je=m,t(57,Ee=A),t(58,Ae=""),t(56,Te=!0)}function uo(){if(se.length===1){const m=he.find(A=>A.id===se[0]);m&&Yt(m.id,m.name)}}async function wl(){const m=Ee.trim();if(!m){t(58,Ae=_("rename.emptyError"));return}try{await $("ValidateName",m)}catch{t(58,Ae=_("rename.invalidError"));return}t(56,Te=!1);const A=je;je="";try{await $("RenameNode",A,m),T&&T.id===A&&t(14,T={...T,title:m}),await Tt(),ce&&await $e(ce)}catch(ne){t(12,S=String(ne))}}function mo(){t(56,Te=!1),je="",t(57,Ee=""),t(58,Ae="")}function po(m){m.key==="Enter"?wl():t(58,Ae="")}function St(m){t(52,De=m.title||_("common.confirm")),t(53,Ue=m.message||""),t(54,Be=m.danger!==void 0?m.danger:!0),t(55,ut=m.confirmText||_("common.delete")),Pe=m.onConfirm||null,We=m.onCancel||null,t(51,Ne=!0)}function zl(){t(51,Ne=!1),Pe=null,We=null}function _o(){Pe&&Pe(),zl()}function vo(){We&&We(),zl()}function Cl(m){t(26,Z=X.node),t(27,J=m),t(25,H=""),t(24,q=!0),kt()}function ho(){t(26,Z=null),t(27,J=void 0),t(25,H=""),t(24,q=!0)}function go(){t(24,q=!1),t(25,H=""),t(26,Z=null),t(27,J=void 0)}async function Sl(){if(!(!H.trim()||J===void 0))try{const m=Z?Z.id:"",A=J?J.id:"",ne=await $("CreateNodeFromTemplate",m,H.trim(),A);t(24,q=!1),t(25,H="");const ke=ne?ne.id:null;if(t(26,Z=null),t(27,J=void 0),m){t(39,Q={...Q,[m]:!0});const ot=await $("ListWorkspaceChildren",m)||[];It(o,m,ot),t(1,o=[...o])}else t(1,o=await $("ListWorkspaceTree")||o);if(ke){const ot=await $("GetNodeDetail",ke);ot&&(t(13,M=""),ft(ot))}}catch(m){t(12,S=String(m))}}function bo(m,A){t(28,X={visible:!0,x:m.clientX,y:m.clientY,node:A})}function kt(){t(28,X={visible:!1,x:0,y:0,node:null})}async function ko(m){const A=!Q[m];if(t(39,Q={...Q,[m]:A}),!A)return;const ne=await $("ListWorkspaceChildren",m)||[];It(o,m,ne),t(1,o=[...o])}async function yo(m,A){if(!(!m||!A||m===A))try{const ne=await $("MoveNode",m,A);await Tt();const ke=await $("GetNodeDetail",m);ke&&(t(13,M=""),ft(ke))}catch(ne){t(12,S=String(ne))}}async function wo(m){m.preventDefault();try{const A=m.dataTransfer.getData("text/plain");if(!A)return;const ne=await $("GetNodeDetail",A);if(!ne||!ne.parent_id)return;await $("MoveNode",A,""),await Tt();const ke=await $("GetNodeDetail",A);ke&&(t(13,M=""),ft(ke))}catch(A){t(12,S=String(A))}}function zo(m){m.preventDefault(),m.dataTransfer.dropEffect="move",t(50,Fe=!0)}function Co(m){t(50,Fe=!1)}function Tl(m){Yt(m.id,m.title),kt()}function jl(m){kt(),St({title:_("delete.confirmTitle"),message:_("delete.confirmMessage")+" "+m.title+"?",confirmText:_("common.delete"),danger:!0,onConfirm:async()=>{try{await $("DeleteNode",m.id),await Tt(),T&&T.id===m.id&&t(14,T=null)}catch(A){t(12,S=String(A))}}})}async function Nl(m){kt();try{await $("OpenFolder",m.id)}catch(A){t(12,S=String(A))}}async function Ml(m){kt();try{await $("MoveNode",m.id,""),await Tt();const A=await $("GetNodeDetail",m.id);A&&(t(13,M=""),ft(A))}catch(A){t(12,S=String(A))}}async function Tt(){const m=Object.keys(Q).filter(ne=>Q[ne]),A=await $("ListWorkspaceTree")||[];for(const ne of m){const ot=(await $("ListWorkspaceChildren",ne)||[]).map(Mt=>({...Mt}));eo(A,ne,ot)}t(1,o=A)}async function Xt(m){const A=await $("ListWorkspaceChildren",m)||[];It(o,m,A),t(1,o=[...o])}function Dl(){t(29,Y=!0),t(30,P="")}function So(){t(29,Y=!1),t(30,P="")}async function Il(){if(!(!P.trim()||!T))try{const m=await $("CreateNote",T.id,P.trim());t(16,D=[...D,m&&m.id?m:{id:Date.now().toString(),title:P.trim(),createdAt:new Date().toISOString()}]),t(29,Y=!1),t(30,P="")}catch{const A={id:Date.now().toString(),title:P.trim(),createdAt:new Date().toISOString()};t(16,D=[...D,A]),t(29,Y=!1),t(30,P="")}}async function jt(m){if(I&&I.dirty){St({title:_("note.unsavedTitle"),message:_("note.unsavedMessage"),confirmText:_("note.unsavedClose"),danger:!1,onConfirm:async()=>{await Fl(m)}});return}await Fl(m)}async function Fl(m){try{const A=await $("ReadNote",m.id);t(17,I={id:m.id,title:m.title,content:A||"",dirty:!1})}catch{t(17,I={id:m.id,title:m.title,content:"# "+m.title+` + +`,dirty:!1})}}function To(){if(I&&I.dirty){St({title:_("note.unsavedTitle"),message:_("note.unsavedMessage"),confirmText:_("note.unsavedClose"),danger:!1,onConfirm:()=>{t(17,I=null)}});return}t(17,I=null)}function jo(m){I&&(t(17,I.content=m.target.value,I),t(17,I.dirty=!0,I))}async function No(){if(I)try{await $("SaveNote",I.id,I.content),t(17,I.dirty=!1,I)}catch{t(17,I.dirty=!1,I)}}async function Mo(){const m=parseInt(U,10);if(!(!K.trim()||isNaN(m)||m<=0||!T)){try{const A=await $("CreateWorklog",T.id,K.trim(),m);t(19,B=[...B,A&&A.id?A:{id:Date.now().toString(),nodeId:T.id,summary:K.trim(),minutes:m,createdAt:new Date().toISOString()}])}catch{t(19,B=[...B,{id:Date.now().toString(),nodeId:T.id,summary:K.trim(),minutes:m,createdAt:new Date().toISOString()}])}t(21,K=""),t(20,U="")}}async function Zt(m){try{await $("AcceptSuggestionWith",m,m.suggestedMin,""),t(22,O=await $("GetSuggestions")||[]),t(23,G=O.length),T&&t(19,B=await $("ListWorklog",T.id)||[])}catch(A){console.error(A)}}async function El(m){try{await $("AcceptSuggestionWith",m,m.suggestedMin,""),t(22,O=await $("GetSuggestions")||[]),t(23,G=O.length),await Qt()}catch(A){console.error(A)}}async function Qt(){try{const[m,A,ne]=await Promise.all([$("ListWorklogReport",v,k,"",g),$("WorklogReportSummary",v,k,"",g),$("GetSuggestions")]);t(5,h=m||[]),t(6,p=A||null),t(22,O=ne||[]),t(23,G=O.length)}catch{t(5,h=[]),t(6,p=null),t(22,O=[]),t(23,G=0)}}async function Do(){try{const m=await $("ExportWorklogCSV",v,k,"",g);Bi("worklog.csv",m,"text/csv")}catch(m){console.error(m)}}async function Io(){try{const m=await $("ExportWorklogMarkdown",v,k,"",g);Bi("worklog.md",m,"text/markdown")}catch(m){console.error(m)}}async function Al(){const m=await $("PickFile");if(!m)return;const A=ce||T.id;await xt(A,m)}async function Fo(){const m=await $("PickDirectory");if(!m)return;const A=ce||T.id;await xt(A,m)}async function xt(m,A){t(36,Me=!0);try{const ne=await $("PreviewImport",A);t(37,Ie=ne),Re=A,V=m,t(38,Ze=!0)}catch(ne){t(12,S=String(ne))}t(36,Me=!1)}async function $t(m){try{const A=V||T.id,ne=m==="copy"?await $("AddPathCopy",A,Re):await $("AddPathLink",A,Re);t(38,Ze=!1),t(37,Ie=null),t(42,ue=[]),t(41,ce=null),await Promise.all([al(A),$e(A),Xt(A)])}catch(A){t(12,S=String(A))}}function Eo(){t(38,Ze=!1),t(37,Ie=null)}async function Ll({id:m,type:A}){const ne=_(A==="folder"?"delete.folder":"delete.file");St({title:_("delete.confirmTitle"),message:_("delete.confirmMessage")+" "+ne+"?",confirmText:_("common.delete"),danger:!0,onConfirm:async()=>{try{await $("DeleteFileOrFolder",m),N=N.filter(ot=>ot.nodeId!==m);const ke=ce||T.id;await $e(ke)}catch(ke){t(12,S=String(ke))}}})}async function Ao(m){if(!m||m.length===0)return;if(!T){t(12,S=_("error.selectCaseFirst"));return}const A=m[0];await xt(T.id,A)}function Lo(m){return{note_created:_("event.noteCreated"),note_updated:_("event.noteUpdated"),file_added:_("event.fileAdded"),file_deleted:_("event.fileDeleted"),file_renamed:_("event.fileRenamed"),file_copied:_("event.fileCopied"),file_moved:_("event.fileMoved"),folder_added:_("event.folderAdded"),folder_deleted:_("event.folderDeleted"),folder_renamed:_("event.folderRenamed"),node_created:_("event.caseCreated"),node_updated:_("event.caseUpdated")}[m]||m}function Po(m){return{project:_("kind.project"),client:_("kind.client"),document:_("kind.document"),recipe:_("kind.recipe"),folder:_("kind.folder"),note:_("kind.note"),file:_("kind.file"),archive:_("kind.archive"),case:_("kind.case")}[m]||m||_("kind.case")}function Oo(){t(31,ee=!0),t(32,ve=""),t(33,te="open_url"),t(34,le="")}function Ro(){t(31,ee=!1),t(32,ve=""),t(34,le="")}async function el(){if(!(!ve.trim()||!le.trim()||!T))try{const m=await $("CreateAction",T.id,te,ve.trim(),le.trim());m&&m.id&&t(18,E=[...E,m]),t(31,ee=!1),t(32,ve=""),t(34,le="")}catch(m){t(12,S=String(m))}}async function Pl(m){try{await $("DeleteAction",m),t(18,E=E.filter(A=>A.id!==m))}catch(A){t(12,S=String(A))}}function Bo(m){const A=oe.find(ne=>ne.id===m);return A?A.label:m}async function it(m){try{const A=await $("GetNodeDetail",m);A&&ft(A)}catch(A){t(12,S=String(A))}}async function Nt(){try{t(60,be=await $("SyncStatus"))}catch{t(60,be={configured:!1,serverUrl:"",deviceId:"",unpushedOps:0,lastSyncAt:"",syncInterval:0})}}function Vo(){t(59,Oe=!0),t(62,Ge=(be==null?void 0:be.serverUrl)||""),t(63,x=""),t(64,pe=""),t(65,Je=(be==null?void 0:be.syncInterval)||0),t(66,Ve="")}function Ho(){t(59,Oe=!1),t(66,Ve="")}async function Uo(){t(61,ze=!0),t(66,Ve="");try{await $("SyncConfigure",Ge,x,pe),Je>0&&await $("SyncSetInterval",Je),t(64,pe=""),t(63,x=""),await Nt(),t(59,Oe=!1)}catch(m){t(66,Ve="err: "+String(m))}t(61,ze=!1)}async function Wo(){t(61,ze=!0),t(66,Ve="");try{await $("SyncSetInterval",Je),t(66,Ve=_("sync.settingsSaved")),await Nt()}catch(m){t(66,Ve="err: "+String(m))}t(61,ze=!1)}async function Ko(){t(61,ze=!0),t(66,Ve="");try{await $("SyncTestConnection",Ge,x,pe),t(66,Ve="connection ok")}catch(m){t(66,Ve="connection failed: "+String(m))}t(61,ze=!1)}async function Go(){t(61,ze=!0),t(66,Ve="");try{await $("SyncDisconnect"),t(66,Ve="disconnected"),await Nt()}catch(m){t(66,Ve="err: "+String(m))}t(61,ze=!1)}async function qo(){t(61,ze=!0),t(66,Ve="");try{const m=await $("SyncNow");t(66,Ve="pushed "+m.pushed+", pulled "+m.pulled+" (seq "+m.serverSequence+")"),await Nt()}catch(m){t(66,Ve="err: "+String(m))}t(61,ze=!1)}const Jo=m=>m.nodeId===T.id,Yo=m=>xe(m.id),Xo=()=>t(12,S=""),Zo=()=>t(12,S=""),Qo=()=>t(12,S="");function xo(){I.content=this.value,t(17,I)}const $o=m=>{t(15,j=m.id),m.id==="files"&&T&&he.length===0&&!ce&&$e(T.id)},es=()=>{t(15,j="notes"),Dl()},ts=()=>{t(15,j="files"),Al()},ls=()=>t(15,j="worklog"),ns=m=>jt(m),is=m=>jt(m);function os(){P=this.value,t(30,P)}const ss=m=>m.key==="Enter"&&Il(),rs=m=>jt(m),cs=m=>jt(m),as=m=>{const A=m.detail;A===0?(t(42,ue=[]),t(41,ce=null),$e(T.id)):ul(A-1)},fs=m=>Kt(m.detail),us=m=>Gt(m.detail),ds=m=>$("OpenFile",m.detail),ms=m=>$("OpenFolder",m.detail),ps=m=>Ll(m.detail),_s=m=>ml(m.detail.id),vs=m=>dl(m.detail),hs=m=>pl(m.detail),gs=m=>_l(m.detail),bs=m=>gl(m.detail),ks=m=>hl(m.detail),ys=m=>bl(m.detail),ws=m=>$("OpenFile",m.detail),zs=m=>$("RunAction",m.id),Cs=m=>Pl(m.id);function Ss(){K=this.value,t(21,K)}function Ts(){U=Bt(this.value),t(20,U)}const js=m=>m.nodeId===T.id,Ns=m=>Zt(m);function Ms(){v=this.value,t(7,v)}function Ds(){k=this.value,t(8,k)}function Is(){g=this.checked,t(9,g)}const Fs=m=>it(m.nodeId),Es=(m,A,ne,ke)=>t(22,A[ne].suggestedMin=parseInt(ke.target.value),O),As=m=>El(m),Ls=m=>it(m.nodeId),Ps=m=>it(m.nodeId),Os=(m,A,ne,ke)=>t(22,A[ne].suggestedMin=parseInt(ke.target.value),O),Rs=m=>Zt(m),Bs=m=>it(m.nodeId),Vs=(m,A)=>A.key==="Enter"&&it(m.nodeId),Hs=m=>it(m.nodeId),Us=(m,A)=>A.key==="Enter"&&it(m.nodeId),Ws=m=>it(m.nodeId),Ks=(m,A)=>A.key==="Enter"&&it(m.nodeId),Gs=m=>it(m.nodeId),qs=(m,A)=>A.key==="Enter"&&it(m.nodeId),Js=()=>t(27,J=null),Ys=m=>t(27,J=m);function Xs(){H=this.value,t(25,H)}const Zs=m=>m.key==="Enter"&&Sl(),Qs=m=>Cl(m),xs=()=>Ml(X.node),$s=()=>Tl(X.node),er=()=>jl(X.node),tr=()=>Nl(X.node);function lr(){ve=this.value,t(32,ve)}const nr=m=>m.key==="Enter"&&el();function ir(){te=kr(this),t(33,te),t(67,oe)}function or(){le=this.value,t(34,le)}const sr=m=>m.key==="Enter"&&el(),rr=()=>$t("copy"),cr=()=>$t("link");function ar(){Ee=this.value,t(57,Ee)}function fr(){Ge=this.value,t(62,Ge)}function ur(){x=this.value,t(63,x)}function dr(){pe=this.value,t(64,pe)}function mr(){Je=Bt(this.value),t(65,Je)}return[n,o,s,r,a,h,p,v,k,g,y,w,S,M,T,j,D,I,E,B,U,K,O,G,q,H,Z,J,X,Y,P,ee,ve,te,le,_e,Me,Ie,Ze,Q,de,ce,ue,he,Ke,Qe,qe,ge,ye,se,Fe,Ne,De,Ue,Be,ut,Te,Ee,Ae,Oe,be,ze,Ge,x,pe,Je,Ve,oe,Lt,xe,ft,$e,Kt,fl,ul,Gt,qt,to,dl,ml,pl,_l,vl,hl,gl,bl,ro,co,ao,wl,mo,po,_o,vo,Cl,ho,go,Sl,bo,kt,ko,yo,wo,zo,Co,Tl,jl,Nl,Ml,Dl,So,Il,jt,To,jo,No,Mo,Zt,El,Qt,Do,Io,Al,Fo,$t,Eo,Ll,Lo,Po,Oo,Ro,el,Pl,Bo,it,Vo,Ho,Uo,Wo,Ko,Go,qo,Jo,Yo,Xo,Zo,Qo,xo,$o,es,ts,ls,ns,is,os,ss,rs,cs,as,fs,us,ds,ms,ps,_s,vs,hs,gs,bs,ks,ys,ws,zs,Cs,Ss,Ts,js,Ns,Ms,Ds,Is,Fs,Es,As,Ls,Ps,Os,Rs,Bs,Vs,Hs,Us,Ws,Ks,Gs,qs,Js,Ys,Xs,Zs,Qs,xs,$s,er,tr,lr,nr,ir,or,sr,rr,cr,ar,fr,ur,dr,mr]}class La extends _t{constructor(e){super(),pt(this,e,Aa,Ea,mt,{},null,[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1])}}new La({target:document.getElementById("app")}); diff --git a/cmd/verstak-gui/frontend-dist/index.html b/cmd/verstak-gui/frontend-dist/index.html index b3b160d..6fbef25 100644 --- a/cmd/verstak-gui/frontend-dist/index.html +++ b/cmd/verstak-gui/frontend-dist/index.html @@ -16,8 +16,8 @@ background: #13131f; } - - + +
diff --git a/docs/PLAN.md b/docs/PLAN.md index cd7eee3..8d0375b 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -25,8 +25,8 @@ | 12 | **Files/Folders full workflow** | ✅ выполнено (copy/link/import/tree) | | 13 | **Drag-and-drop** | ✅ выполнено (internal + external drops) | | 14 | **MVP stabilization** | ✅ выполнено | -| 15 | **Sync Server + Client** | 🔄 в работе — HTTP API, push/pull, blob sync | -| 16 | **Activity Suggestions** | ⏳ ожидает — подсказки из activity_events | +| 15 | **Sync Server + Client** | ✅ выполнено | +| 16 | **Activity Suggestions** | 🔄 в работе — global worklog dashboard + conservative suggestions + UX | | 17 | **File Scanner/Watcher** | ⏳ ожидает — fsnotify, snapshot scanner | | 18 | **TUI MVP (Bubble Tea)** | ⏳ ожидает — tree/search, add worklog | | 19 | **Plugins: Lua runtime** | ⏳ ожидает — gopher-lua, hooks, sandbox | @@ -167,15 +167,25 @@ Core service extensions: --- -## Текущий этап: ШАГ 15 — Sync Server + Client +## Текущий этап: ШАГ 16 — Activity Suggestions -**Статус:** ✅ Сервер собран и работает. Клиент реализован. Нужна доработка и тестирование. +**Статус:** 🔄 в работе — activity-based suggestions + global worklog dashboard + conservative estimator. -Стек синхронизации: -- `cmd/verstak-server/` — HTTP API сервер (порт, API key, push/pull) -- `internal/core/sync/` — клиент синхронизации -- SQLite-based sync state (`migrations/008_sync.sql`) -- FS-first apply: изменения применяются через файловую систему, БД — индекс +Что реализовано: +- `suggest.go` — структура Suggestion (nodeId, nodeTitle, summary, suggestedMin, confidence) +- `bindings_suggest.go` — GetSuggestions с burst detection + conservative estimator (5–30 min) +- `bindings_suggest.go` — AcceptSuggestionWith (date/minutes overrides) +- `worklog/report.go` — ReportFilter, ListReport, Summary, ExportCSV, ExportMarkdown +- `app.go` — WorklogDTO расширен: date, details, approximate, billable, nodeTitle +- `bindings_worklog.go` — CreateWorklogFull, ListWorklogReport, WorklogSummary, Export* +- Новый системный раздел "Журнал" с таблицей, фильтрами (даты, includeChildren), сводкой +- Предложения на экране "Сегодня" + вкладке "Журнал" + вкладке "Журнал дела" +- Badge с количеством предложений в боковом меню +- Консервативный estimator: + - burst detection (группировка событий в окне 10 мин) + - time spread analysis + - 5–30 мин, 60+ только при сильном evidence + - Confidence: low/medium/high + reason --- diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index ce11f8c..525429f 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -34,6 +34,11 @@ let activityFeed = [] let activityOffset = 0 let activityHasMore = true + let journalRows = [] + let journalSummary = null + let journalDateFrom = '' + let journalDateTo = '' + let journalIncludeChildren = false let activityLoading = false let caseActivity = [] let version = '' @@ -49,6 +54,7 @@ let worklogMinutes = '' let worklogSummary = '' let suggestions = [] + let suggestionCount = 0 let showCreateNode = false let newNodeTitle = '' let createInNode = null @@ -177,9 +183,15 @@ activityFeed = [] activityOffset = 0 activityHasMore = true + journalRows = [] + journalSummary = null try { if (id === 'today') { todayDashboard = await wailsCall('ListTodayView') || { cases: [] } + suggestions = await wailsCall('GetSuggestions') || [] + suggestionCount = suggestions.length + } else if (id === 'journal') { + await loadJournal() } else if (id === 'activity') { activityFeed = await wailsCall('ListActivityFeed', 50, 0) || [] activityOffset = activityFeed.length @@ -220,7 +232,10 @@ try { files = await wailsCall('ListFiles', nodeID) || [] } catch(e) {} try { actions = await wailsCall('ListActions', nodeID) || [] } catch(e) {} try { worklog = await wailsCall('ListWorklog', nodeID) || [] } catch(e) {} - try { suggestions = await wailsCall('GetSuggestions') || [] } catch(e) { suggestions = [] } + try { + suggestions = await wailsCall('GetSuggestions') || [] + suggestionCount = suggestions.length + } catch(e) { suggestions = []; suggestionCount = 0 } try { caseActivity = await wailsCall('ListActivityByNode', nodeID, 50, 0) || [] } catch(e) {} } @@ -913,18 +928,84 @@ worklogMinutes = '' } + async function acceptTodaySuggestion(s) { + try { + await wailsCall('AcceptSuggestionWith', s, s.suggestedMin, '') + suggestions = await wailsCall('GetSuggestions') || [] + suggestionCount = suggestions.length + if (selectedNode) { + worklog = await wailsCall('ListWorklog', selectedNode.id) || [] + } + } catch (e) { console.error(e) } + } + + async function acceptJournalSuggestion(s) { + try { + await wailsCall('AcceptSuggestionWith', s, s.suggestedMin, '') + suggestions = await wailsCall('GetSuggestions') || [] + suggestionCount = suggestions.length + await loadJournal() + } catch (e) { console.error(e) } + } + async function acceptSuggestion(s) { try { - await wailsCall('AcceptSuggestion', s) + await wailsCall('AcceptSuggestionWith', s, s.suggestedMin, '') + suggestions = await wailsCall('GetSuggestions') || [] + suggestionCount = suggestions.length if (selectedNode) { - try { worklog = await wailsCall('ListWorklog', selectedNode.id) || [] } catch(e) {} - try { suggestions = await wailsCall('GetSuggestions') || [] } catch(e) { suggestions = [] } + worklog = await wailsCall('ListWorklog', selectedNode.id) || [] } } catch (e) { console.error('accept suggestion', e) } } + // ===== Journal ===== + async function loadJournal() { + try { + const [rows, summary, sugs] = await Promise.all([ + wailsCall('ListWorklogReport', journalDateFrom, journalDateTo, '', journalIncludeChildren), + wailsCall('WorklogReportSummary', journalDateFrom, journalDateTo, '', journalIncludeChildren), + wailsCall('GetSuggestions'), + ]) + journalRows = rows || [] + journalSummary = summary || null + suggestions = sugs || [] + suggestionCount = suggestions.length + } catch (e) { + journalRows = [] + journalSummary = null + suggestions = [] + suggestionCount = 0 + } + } + + async function exportJournalCSV() { + try { + const csv = await wailsCall('ExportWorklogCSV', journalDateFrom, journalDateTo, '', journalIncludeChildren) + downloadFile('worklog.csv', csv, 'text/csv') + } catch (e) { console.error(e) } + } + + async function exportJournalMarkdown() { + try { + const md = await wailsCall('ExportWorklogMarkdown', journalDateFrom, journalDateTo, '', journalIncludeChildren) + downloadFile('worklog.md', md, 'text/markdown') + } catch (e) { console.error(e) } + } + + function downloadFile(name, content, mime) { + const blob = new Blob([content], { type: mime }) + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url; a.download = name + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + } + // ===== Files ===== async function addFile() { const path = await wailsCall('PickFile') @@ -1220,6 +1301,9 @@ {/each} @@ -1522,17 +1606,19 @@ disabled={!worklogSummary.trim() || !worklogMinutes}>{t('worklog.log')} {#if selectedNode && suggestions.filter(s => s.nodeId === selectedNode.id).length > 0} -
+
{t('worklog.suggestions')}
{#each suggestions.filter(s => s.nodeId === selectedNode.id) as s} -
-
-
{s.summary}
-
{s.suggestedMin} {t('worklog.min')}
+
+
+ {s.summary} + {s.suggestedMin} {t('worklog.min')} · {t('suggest.confidence.' + s.confidence)} +
+
+
-
{/each}
@@ -1570,6 +1656,104 @@ {/if}
+ {:else if selectedSection === 'journal'} +
+
+

{t('journal.title')}

+
+ + + + + + +
+
+ + {#if suggestions.length > 0} +
+
{t('suggest.title')}
+ {#each suggestions as s} +
+
+ + {s.summary} + {t('suggest.confidence.' + s.confidence)} +
+
+ s.suggestedMin = parseInt(e.target.value)} /> + {t('suggest.minutes')} + +
+
+ {/each} +
+ {/if} + + {#if journalSummary} +
+
{t('journal.total')}: {Math.floor(journalSummary.totalMinutes / 60)}ч {journalSummary.totalMinutes % 60}м ({journalSummary.totalEntries} {t('worklog.min')})
+ {#if journalSummary.byDay && journalSummary.byDay.length > 0} +
+
{t('journal.byDay')}
+ {#each journalSummary.byDay as g} +
{g.label}{Math.floor(g.minutes / 60)}ч {g.minutes % 60}м{g.count}
+ {/each} +
+ {/if} + {#if journalSummary.byNode && journalSummary.byNode.length > 0} +
+
{t('journal.byNode')}
+ {#each journalSummary.byNode as g} +
{g.label}{Math.floor(g.minutes / 60)}ч {g.minutes % 60}м{g.count}
+ {/each} +
+ {/if} +
+ {/if} + + {#if journalRows.length === 0} +

{t('journal.empty')}

+ {:else} +
+ + + + + + + + + + + + + + {#each journalRows as r} + + + + + + + + + + {/each} + +
{t('journal.title')}{t('journal.node')}{t('journal.path')}{t('worklog.minutes')}{t('journal.billable')}{t('journal.approximate')}{t('common.date')}
{r.summary}{r.nodePath}{r.minutes}{#if r.billable}✓{/if}{#if r.approximate}~{/if}{r.date}
+
+ {/if} +
+ {:else if selectedSection === 'today' && todayDashboard}
@@ -1584,6 +1768,27 @@
{/if} + {#if suggestions.length > 0} +
+
{t('suggest.title')}
+ {#each suggestions as s} +
+
+ + {s.summary} + {t('suggest.confidence.' + s.confidence)} +
+
+ s.suggestedMin = parseInt(e.target.value)} /> + {t('suggest.minutes')} + +
+
+ {/each} +
+ {/if} + {#if todayDashboard.groups && todayDashboard.groups.length > 0} {#each todayDashboard.groups as group}
@@ -2029,13 +2234,58 @@ .worklog-form input[type="text"] { flex: 1; } .worklog-form input[type="number"] { width: 70px; } .worklog-entry { padding: 12px 0; border-bottom: 1px solid #1a1a28; } -.suggestions { margin-bottom: 24px; padding: 16px; background: #1a1a2e; border-radius: 8px; border: 1px solid #2a2a3c; } .suggestions-title { font-size: 13px; font-weight: 600; color: #a5b4fc; margin-bottom: 12px; text-transform: uppercase; letter-spacing: 0.5px; } -.suggestion { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #2a2a3c; } -.suggestion:last-child { border-bottom: none; } -.suggestion-body { flex: 1; } .suggestion-summary { font-size: 14px; color: #e4e4ef; } .suggestion-meta { font-size: 12px; color: #8888a0; margin-top: 2px; } + +/* Suggestion cards */ +.suggestion-card { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; background: #1e1e32; border-radius: 6px; margin-bottom: 8px; gap: 12px; } +.suggestion-card:last-child { margin-bottom: 0; } +.suggestion-info { flex: 1; display: flex; flex-direction: column; gap: 2px; } +.suggestion-node { color: #a5b4fc; font-weight: 600; font-size: 13px; text-decoration: none; cursor: pointer; } +.suggestion-node:hover { text-decoration: underline; } +.suggestion-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; } +.suggestion-min-input { width: 60px; padding: 4px 8px; border: 1px solid #2a2a3c; background: #13131f; color: #e4e4ef; border-radius: 4px; font-size: 14px; text-align: center; } +.suggestion-min-label { font-size: 12px; color: #8888a0; } +.suggestion-confidence { font-size: 11px; padding: 2px 6px; border-radius: 3px; } +.suggestion-confidence.low { color: #fbbf24; } +.suggestion-confidence.medium { color: #60a5fa; } +.suggestion-confidence.high { color: #34d399; } + +/* Journal screen */ +.journal-screen { padding: 24px; overflow-y: auto; flex: 1; } +.journal-header { margin-bottom: 24px; } +.journal-header h2 { margin: 0 0 16px 0; } +.journal-filters { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; } +.journal-filters label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: #8888a0; } +.journal-filters input[type="date"] { padding: 6px 10px; border: 1px solid #2a2a3c; background: #13131f; color: #e4e4ef; border-radius: 4px; font-size: 13px; font-family: inherit; } +.journal-filters .checkbox-label { flex-direction: row; align-items: center; gap: 6px; cursor: pointer; } +.journal-filters .checkbox-label input { width: auto; } +.journal-summary { display: flex; flex-wrap: wrap; gap: 24px; margin-bottom: 24px; padding: 16px; background: #1a1a2e; border-radius: 8px; border: 1px solid #2a2a3c; } +.summary-total { font-size: 18px; font-weight: 700; color: #e4e4ef; width: 100%; margin-bottom: 4px; } +.summary-section { flex: 1; min-width: 200px; } +.summary-label { font-size: 12px; font-weight: 600; color: #a5b4fc; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; } +.summary-row { display: flex; gap: 8px; font-size: 13px; padding: 4px 0; border-bottom: 1px solid #2a2a3c; } +.summary-row span:first-child { flex: 1; color: #e4e4ef; } +.summary-count { color: #8888a0; } +.journal-table-wrap { overflow-x: auto; } +.journal-table { width: 100%; border-collapse: collapse; font-size: 13px; } +.journal-table th { text-align: left; padding: 8px 12px; border-bottom: 2px solid #2a2a3c; color: #8888a0; font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; } +.journal-table td { padding: 8px 12px; border-bottom: 1px solid #1a1a28; color: #e4e4ef; } +.journal-table .link-btn { color: #a5b4fc; } +.journal-path-cell { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #8888a0; font-size: 12px; } +.journal-min-cell { text-align: right; font-variant-numeric: tabular-nums; } +.journal-date-cell { color: #8888a0; white-space: nowrap; } + +/* Today suggestions */ +.today-suggestions { margin-bottom: 24px; } + +/* Link-style buttons */ +.link-btn { background: none; border: none; padding: 0; color: #a5b4fc; font: inherit; cursor: pointer; text-align: left; } +.link-btn:hover { text-decoration: underline; } + +/* Nav badge */ +.nav-badge { background: #6366f1; color: #fff; font-size: 10px; font-weight: 700; border-radius: 10px; padding: 1px 6px; margin-left: 6px; line-height: 1.4; } .wl-meta { font-size: 11px; color: #555; margin-top: 2px; } /* Actions */ diff --git a/frontend/src/lib/i18n/locales/en.js b/frontend/src/lib/i18n/locales/en.js index af5cc0d..f1228fe 100644 --- a/frontend/src/lib/i18n/locales/en.js +++ b/frontend/src/lib/i18n/locales/en.js @@ -123,4 +123,33 @@ export default { 'worklog.suggestions': 'Suggestions for today', 'worklog.apply': 'Apply', + + 'nav.journal': 'Journal', + + 'journal.title': 'Work Log', + 'journal.empty': 'No entries for the selected period', + 'journal.dateFrom': 'From', + 'journal.dateTo': 'To', + 'journal.filter': 'Filter', + 'journal.total': 'Total', + 'journal.exportCSV': 'CSV', + 'journal.exportMarkdown': 'Markdown', + 'journal.billable': 'Billable', + 'journal.approximate': 'Approx', + 'journal.node': 'Case', + 'journal.path': 'Path', + 'journal.byDay': 'By day', + 'journal.byNode': 'By case', + 'journal.includeChildren': 'Include subtasks', + + 'suggest.title': 'Suggestions', + 'suggest.apply': 'Log', + 'suggest.dismiss': 'Dismiss', + 'suggest.open': 'Open', + 'suggest.confidence.low': 'Low confidence', + 'suggest.confidence.medium': 'Medium confidence', + 'suggest.confidence.high': 'High confidence', + 'suggest.minutes': 'min', + 'suggest.edit': 'Edit', + 'suggest.noSuggestions': 'No suggestions', } diff --git a/frontend/src/lib/i18n/locales/ru.js b/frontend/src/lib/i18n/locales/ru.js index c6be5df..3c83054 100644 --- a/frontend/src/lib/i18n/locales/ru.js +++ b/frontend/src/lib/i18n/locales/ru.js @@ -2,6 +2,7 @@ export default { 'nav.today': 'Сегодня', 'nav.inbox': 'Неразобранное', 'nav.activity': 'Активность', + 'nav.journal': 'Журнал', 'nav.clients': 'Клиенты', 'nav.projects': 'Проекты', 'nav.recipes': 'Рецепты', @@ -198,6 +199,33 @@ export default { 'today.plural.event_few': 'события', 'today.plural.event_many': 'событий', + 'journal.title': 'Журнал работы', + 'journal.empty': 'Нет записей за выбранный период', + 'journal.dateFrom': 'От', + 'journal.dateTo': 'До', + 'journal.filter': 'Фильтр', + 'journal.total': 'Всего', + 'journal.exportCSV': 'CSV', + 'journal.exportMarkdown': 'Markdown', + 'journal.billable': 'Оплачиваемое', + 'journal.approximate': 'Примерно', + 'journal.node': 'Дело', + 'journal.path': 'Путь', + 'journal.byDay': 'По дням', + 'journal.byNode': 'По делам', + 'journal.includeChildren': 'С подзадачами', + + 'suggest.title': 'Предложения на сегодня', + 'suggest.apply': 'Записать', + 'suggest.dismiss': 'Скрыть', + 'suggest.open': 'Открыть', + 'suggest.confidence.low': 'Низкая уверенность', + 'suggest.confidence.medium': 'Средняя уверенность', + 'suggest.confidence.high': 'Высокая уверенность', + 'suggest.minutes': 'мин', + 'suggest.edit': 'Изменить', + 'suggest.noSuggestions': 'Нет предложений для журнала', + 'activity.title': 'Активность', 'activity.empty': 'Активность пока не зафиксирована', 'activity.perCaseEmpty': 'Активность пока не зафиксирована', diff --git a/internal/core/activity/suggest.go b/internal/core/activity/suggest.go index 345ee4e..ea6fa3d 100644 --- a/internal/core/activity/suggest.go +++ b/internal/core/activity/suggest.go @@ -1,11 +1,22 @@ package activity +// Confidence level for a suggestion. +const ( + ConfidenceLow = "low" + ConfidenceMedium = "medium" + ConfidenceHigh = "high" +) + // Suggestion represents a suggested worklog entry derived from today's activity. type Suggestion struct { - NodeID string `json:"nodeId"` - NodeTitle string `json:"nodeTitle"` - Summary string `json:"summary"` - SuggestedMin int `json:"suggestedMin"` - EventCount int `json:"eventCount"` - NodeKind string `json:"nodeKind"` + NodeID string `json:"nodeId"` + NodeTitle string `json:"nodeTitle"` + Summary string `json:"summary"` + SuggestedMin int `json:"suggestedMin"` + EventCount int `json:"eventCount"` + NodeKind string `json:"nodeKind"` + Confidence string `json:"confidence"` + ConfidenceReason string `json:"confidenceReason"` + Hidden bool `json:"hidden"` + TimeSpreadMin int `json:"timeSpreadMin"` // minutes between first and last event } diff --git a/internal/core/worklog/report.go b/internal/core/worklog/report.go new file mode 100644 index 0000000..ef1dd74 --- /dev/null +++ b/internal/core/worklog/report.go @@ -0,0 +1,398 @@ +package worklog + +import ( + "fmt" + "strings" + "time" + + "verstak/internal/core/storage" + "verstak/internal/core/util" +) + +// ReportFilter specifies which worklog entries to include. +type ReportFilter struct { + DateFrom string // "2006-01-02" or "" for no lower bound + DateTo string // "2006-01-02" or "" for no upper bound + NodeID string // optional filter by node + IncludeChildren bool // include descendants of NodeID + Billable *bool // nil = all, true/false to filter + Approximate *bool // nil = all + Section string // filter by node section (requires JOIN) +} + +// ReportRow is a single worklog entry with node info. +type ReportRow struct { + ID string `json:"id"` + NodeID string `json:"nodeId"` + NodeTitle string `json:"nodeTitle"` + NodePath string `json:"nodePath"` + Date string `json:"date"` + Summary string `json:"summary"` + Details string `json:"details"` + Minutes int `json:"minutes"` + Approximate bool `json:"approximate"` + Billable bool `json:"billable"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` +} + +// SummaryGroup aggregates worklog minutes by a key. +type SummaryGroup struct { + Label string `json:"label"` + Minutes int `json:"minutes"` + Count int `json:"count"` +} + +// ReportSummary contains aggregated totals. +type ReportSummary struct { + TotalMinutes int `json:"totalMinutes"` + TotalEntries int `json:"totalEntries"` + ByDay []SummaryGroup `json:"byDay"` + ByNode []SummaryGroup `json:"byNode"` +} + +// nodeTitleAndParents returns title and full path for a node. +// Path is constructed by walking up parent_id chain. +func (s *Service) nodeTitleAndParents(nodeID string) (title, path string) { + type nodeRow struct { + id string + parentID *string + title string + } + + // Walk up the chain. + currentID := nodeID + var chain []string + var nodeTitle string + seen := make(map[string]bool) + maxDepth := 10 + + for i := 0; i < maxDepth; i++ { + if currentID == "" || seen[currentID] { + break + } + seen[currentID] = true + + var nr nodeRow + err := s.db.QueryRow( + `SELECT id, parent_id, title FROM nodes WHERE id = ?`, currentID, + ).Scan(&nr.id, &nr.parentID, &nr.title) + if err != nil { + break + } + if nodeTitle == "" { + nodeTitle = nr.title + } + chain = append([]string{nr.title}, chain...) + if nr.parentID == nil { + break + } + currentID = *nr.parentID + } + return nodeTitle, strings.Join(chain, " > ") +} + +// buildReportQuery constructs the SQL for a filtered worklog report. +func (s *Service) buildReportQuery(f ReportFilter) (string, []interface{}) { + var conditions []string + var args []interface{} + + if f.DateFrom != "" { + conditions = append(conditions, "w.date >= ?") + args = append(args, f.DateFrom) + } + if f.DateTo != "" { + conditions = append(conditions, "w.date <= ?") + args = append(args, f.DateTo) + } + if f.Billable != nil { + conditions = append(conditions, "w.billable = ?") + v := 0 + if *f.Billable { + v = 1 + } + args = append(args, v) + } + if f.Approximate != nil { + conditions = append(conditions, "w.approximate = ?") + v := 0 + if *f.Approximate { + v = 1 + } + args = append(args, v) + } + if f.NodeID != "" { + if f.IncludeChildren { + conditions = append(conditions, `(w.node_id = ? OR w.node_id IN ( + WITH RECURSIVE descs AS ( + SELECT id FROM nodes WHERE parent_id = ? + UNION ALL + SELECT n.id FROM nodes n JOIN descs d ON n.parent_id = d.id + ) SELECT id FROM descs + ))`) + args = append(args, f.NodeID, f.NodeID) + } else { + conditions = append(conditions, "w.node_id = ?") + args = append(args, f.NodeID) + } + } + + whereClause := "" + if len(conditions) > 0 { + whereClause = " WHERE " + strings.Join(conditions, " AND ") + } + + q := `SELECT w.id, w.node_id, COALESCE(n.title,''), w.date, w.summary, + COALESCE(w.details,''), COALESCE(w.minutes,0), w.approximate, w.billable, + w.created_at, w.updated_at + FROM worklog_entries w + LEFT JOIN nodes n ON n.id = w.node_id` + + whereClause + + ` ORDER BY w.date DESC, w.created_at DESC` + + return q, args +} + +// ListReport returns filtered worklog entries with node info. +func (s *Service) ListReport(f ReportFilter) ([]ReportRow, error) { + q, args := s.buildReportQuery(f) + rows, err := s.db.Query(q, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + var out []ReportRow + for rows.Next() { + var r ReportRow + var createdStr, updatedStr string + var approxInt, billInt int + err := rows.Scan(&r.ID, &r.NodeID, &r.NodeTitle, &r.Date, + &r.Summary, &r.Details, &r.Minutes, &approxInt, &billInt, + &createdStr, &updatedStr) + if err != nil { + return nil, err + } + r.Approximate = approxInt == 1 + r.Billable = billInt == 1 + r.CreatedAt = createdStr + r.UpdatedAt = updatedStr + + // Build path lazily only if needed. + if r.NodeTitle == "" { + title, _ := s.nodeTitleAndParents(r.NodeID) + r.NodeTitle = title + } + + out = append(out, r) + } + return out, rows.Err() +} + +// BuildReportPaths enriches report rows with node paths. +func (s *Service) BuildReportPaths(rows []ReportRow) { + pathCache := make(map[string]string, len(rows)) + for i := range rows { + if rows[i].NodePath != "" { + continue + } + if p, ok := pathCache[rows[i].NodeID]; ok { + rows[i].NodePath = p + continue + } + _, path := s.nodeTitleAndParents(rows[i].NodeID) + pathCache[rows[i].NodeID] = path + rows[i].NodePath = path + } +} + +// Summary aggregates worklog entries matching the filter. +func (s *Service) Summary(f ReportFilter) (*ReportSummary, error) { + rows, err := s.ListReport(f) + if err != nil { + return nil, err + } + + sm := &ReportSummary{} + dayMap := make(map[string]int) + dayCount := make(map[string]int) + nodeMap := make(map[string]int) + nodeCount := make(map[string]int) + + for _, r := range rows { + sm.TotalMinutes += r.Minutes + sm.TotalEntries++ + dayMap[r.Date] += r.Minutes + dayCount[r.Date]++ + nodeMap[r.NodeTitle] += r.Minutes + nodeCount[r.NodeTitle]++ + } + + for day, min := range dayMap { + sm.ByDay = append(sm.ByDay, SummaryGroup{Label: day, Minutes: min, Count: dayCount[day]}) + } + for node, min := range nodeMap { + sm.ByNode = append(sm.ByNode, SummaryGroup{Label: node, Minutes: min, Count: nodeCount[node]}) + } + + return sm, nil +} + +// ExportCSV returns a CSV string of the filtered report. +func (s *Service) ExportCSV(f ReportFilter) (string, error) { + rows, err := s.ListReport(f) + if err != nil { + return "", err + } + s.BuildReportPaths(rows) + + var b strings.Builder + b.WriteString("Date,Node,Path,Summary,Minutes,Approximate,Billable,Created\n") + for _, r := range rows { + approx := "0" + if r.Approximate { + approx = "1" + } + bill := "0" + if r.Billable { + bill = "1" + } + summary := strings.ReplaceAll(r.Summary, "\"", "\"\"") + b.WriteString(fmt.Sprintf("%s,\"%s\",\"%s\",\"%s\",%d,%s,%s,%s\n", + r.Date, r.NodeTitle, r.NodePath, summary, r.Minutes, approx, bill, r.CreatedAt)) + } + return b.String(), nil +} + +// ExportMarkdown returns a Markdown report. +func (s *Service) ExportMarkdown(f ReportFilter) (string, error) { + rows, err := s.ListReport(f) + if err != nil { + return "", err + } + s.BuildReportPaths(rows) + + sm, _ := s.Summary(f) + + var b strings.Builder + b.WriteString("# Worklog Report\n\n") + + period := "" + if f.DateFrom != "" || f.DateTo != "" { + period = fmt.Sprintf(" (%s – %s)", f.DateFrom, f.DateTo) + } + b.WriteString(fmt.Sprintf("**Period:**%s\n\n", period)) + if sm != nil { + b.WriteString(fmt.Sprintf("**Total:** %dh %dm (%d entries)\n\n", + sm.TotalMinutes/60, sm.TotalMinutes%60, sm.TotalEntries)) + } + + b.WriteString("| Date | Node | Path | Summary | Minutes |\n") + b.WriteString("|------|------|------|---------|--------|\n") + for _, r := range rows { + approx := "" + if r.Approximate { + approx = " ~" + } + b.WriteString(fmt.Sprintf("| %s | %s | %s | %s | %d%s |\n", + r.Date, r.NodeTitle, r.NodePath, r.Summary, r.Minutes, approx)) + } + + if sm != nil { + b.WriteString("\n## Summary\n\n") + b.WriteString(fmt.Sprintf("**Total:** %dh %dm\n\n", sm.TotalMinutes/60, sm.TotalMinutes%60)) + + if len(sm.ByDay) > 0 { + b.WriteString("### By Day\n\n") + b.WriteString("| Date | Minutes | Entries |\n") + b.WriteString("|------|---------|--------|\n") + for _, d := range sm.ByDay { + b.WriteString(fmt.Sprintf("| %s | %dh %dm | %d |\n", d.Label, d.Minutes/60, d.Minutes%60, d.Count)) + } + b.WriteString("\n") + } + } + + return b.String(), nil +} + +// GetByIDWithNode returns a single entry with node title. +func (s *Service) GetByIDWithNode(id string) (*ReportRow, error) { + q := `SELECT w.id, w.node_id, COALESCE(n.title,''), w.date, w.summary, + COALESCE(w.details,''), COALESCE(w.minutes,0), w.approximate, w.billable, + w.created_at, w.updated_at + FROM worklog_entries w + LEFT JOIN nodes n ON n.id = w.node_id + WHERE w.id = ?` + var r ReportRow + var createdStr, updatedStr string + var approxInt, billInt int + err := s.db.QueryRow(q, id).Scan(&r.ID, &r.NodeID, &r.NodeTitle, &r.Date, + &r.Summary, &r.Details, &r.Minutes, &approxInt, &billInt, + &createdStr, &updatedStr) + if err != nil { + return nil, err + } + r.Approximate = approxInt == 1 + r.Billable = billInt == 1 + r.CreatedAt = createdStr + r.UpdatedAt = updatedStr + return &r, nil +} + +// AddWithDate inserts a worklog entry with a specific date. +func (s *Service) AddWithDate(nodeID, summary, details, date string, minutes int, approximate, billable bool) (*Entry, error) { + if nodeID == "" { + return nil, fmt.Errorf("node_id required") + } + if summary == "" { + return nil, fmt.Errorf("summary required") + } + if date == "" { + date = time.Now().Format("2006-01-02") + } + + e := &Entry{ + ID: util.UUID7(), + NodeID: nodeID, + Summary: summary, + Details: details, + Date: date, + Minutes: &minutes, + Approximate: approximate, + Billable: billable, + CreatedAt: time.Now().UTC(), + UpdatedAt: time.Now().UTC(), + } + + _, err := s.db.Exec( + `INSERT INTO worklog_entries (id,node_id,date,minutes,approximate,billable, + summary,details,created_at,updated_at) + VALUES (?,?,?,?,?,?,?,?,?,?)`, + e.ID, e.NodeID, e.Date, e.Minutes, boolInt(e.Approximate), + boolInt(e.Billable), e.Summary, e.Details, + e.CreatedAt.Format(time.RFC3339), e.UpdatedAt.Format(time.RFC3339), + ) + if err != nil { + return nil, err + } + return e, nil +} + +// UpdateDate updates the date of an entry. +func (s *Service) UpdateDate(id, date string) error { + t := time.Now().UTC().Format(time.RFC3339) + res, err := s.db.Exec( + `UPDATE worklog_entries SET date=?, updated_at=? WHERE id=?`, + date, t, id) + if err != nil { + return err + } + n, _ := res.RowsAffected() + if n == 0 { + return fmt.Errorf("entry not found") + } + return nil +} + +var _ = storage.DB{} diff --git a/internal/core/worklog/worklog.go b/internal/core/worklog/worklog.go index ec6cad7..0219e29 100644 --- a/internal/core/worklog/worklog.go +++ b/internal/core/worklog/worklog.go @@ -50,7 +50,7 @@ func (s *Service) Add(nodeID, summary, details string, minutes int, approximate, NodeID: nodeID, Summary: summary, Details: details, - Date: time.Now().UTC().Format("2006-01-02"), + Date: time.Now().Format("2006-01-02"), Minutes: &minutes, Approximate: approximate, Billable: billable,