@tequila99/githuman 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -0
  3. package/dist/cli/commands/export.js +55 -0
  4. package/dist/cli/commands/list.js +39 -0
  5. package/dist/cli/config.js +65 -0
  6. package/dist/cli/index.js +50 -0
  7. package/dist/cli/server-runtime.js +66 -0
  8. package/dist/cli/startup-message.js +7 -0
  9. package/dist/server/app.js +62 -0
  10. package/dist/server/db/index.js +17 -0
  11. package/dist/server/db/migrations.js +34 -0
  12. package/dist/server/event-bus.js +14 -0
  13. package/dist/server/repositories/comment.repo.js +52 -0
  14. package/dist/server/repositories/review.repo.js +41 -0
  15. package/dist/server/routes/comments.js +114 -0
  16. package/dist/server/routes/diff.js +39 -0
  17. package/dist/server/routes/events.js +16 -0
  18. package/dist/server/routes/export.js +27 -0
  19. package/dist/server/routes/git.js +100 -0
  20. package/dist/server/routes/health.js +5 -0
  21. package/dist/server/routes/reviews.js +90 -0
  22. package/dist/server/services/comment.service.js +57 -0
  23. package/dist/server/services/diff.service.js +144 -0
  24. package/dist/server/services/export.service.js +71 -0
  25. package/dist/server/services/file-watcher.service.js +124 -0
  26. package/dist/server/services/git.service.js +219 -0
  27. package/dist/server/services/review.service.js +71 -0
  28. package/dist/shared/types.js +4 -0
  29. package/dist/web/assets/ErrorNotFound-C0A8n_dh.js +1 -0
  30. package/dist/web/assets/IndexPage-Ca7Xb-lc.js +3 -0
  31. package/dist/web/assets/IndexPage-Dn15ye8s.css +1 -0
  32. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuYjalmUiAw-BCOjigVR.woff +0 -0
  33. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuZtalmUiAw-Ocp2tNig.woff +0 -0
  34. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWuaabVmUiAw-6jEn9xEl.woff +0 -0
  35. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWub2bVmUiAw-CCs8I9zJ.woff +0 -0
  36. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbFmUiAw-BLaboPi0.woff +0 -0
  37. package/dist/web/assets/KFOMCnqEu92Fr1ME7kSn66aGLdTylUAMQXC89YmC2DPNWubEbVmUiAw-DHuK6FBl.woff +0 -0
  38. package/dist/web/assets/MainLayout-CC5JJvA9.css +1 -0
  39. package/dist/web/assets/MainLayout-DHuQjMOV.js +1 -0
  40. package/dist/web/assets/QPage-DLIDrL1Z.js +1 -0
  41. package/dist/web/assets/ReviewsPage-f8fJEuU9.js +1 -0
  42. package/dist/web/assets/bash-CLZ0U2zV.js +1 -0
  43. package/dist/web/assets/client-TNhDHmkt.js +1 -0
  44. package/dist/web/assets/core-Ruj7F7dx.js +12 -0
  45. package/dist/web/assets/create-C46qMo0y.js +1 -0
  46. package/dist/web/assets/css-CdtkT07m.js +1 -0
  47. package/dist/web/assets/css-LbU1hoFO.js +1 -0
  48. package/dist/web/assets/engine-oniguruma-Bon2Icja.js +1 -0
  49. package/dist/web/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
  50. package/dist/web/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
  51. package/dist/web/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
  52. package/dist/web/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
  53. package/dist/web/assets/fira-code-cyrillic-600-normal-BD56RyRT.woff +0 -0
  54. package/dist/web/assets/fira-code-cyrillic-600-normal-CPRdbepc.woff2 +0 -0
  55. package/dist/web/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
  56. package/dist/web/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
  57. package/dist/web/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
  58. package/dist/web/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
  59. package/dist/web/assets/fira-code-cyrillic-ext-600-normal-B9wE0zmr.woff2 +0 -0
  60. package/dist/web/assets/fira-code-cyrillic-ext-600-normal-DldcyWhZ.woff +0 -0
  61. package/dist/web/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
  62. package/dist/web/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
  63. package/dist/web/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
  64. package/dist/web/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
  65. package/dist/web/assets/fira-code-greek-600-normal-D_h3X2X5.woff +0 -0
  66. package/dist/web/assets/fira-code-greek-600-normal-Dxp52_By.woff2 +0 -0
  67. package/dist/web/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
  68. package/dist/web/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
  69. package/dist/web/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
  70. package/dist/web/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
  71. package/dist/web/assets/fira-code-greek-ext-600-normal-C-cQDoOk.woff +0 -0
  72. package/dist/web/assets/fira-code-greek-ext-600-normal-DtBpFRLc.woff2 +0 -0
  73. package/dist/web/assets/fira-code-latin-400-normal-C-QZfXAs.woff +0 -0
  74. package/dist/web/assets/fira-code-latin-400-normal-DGosTW8U.woff2 +0 -0
  75. package/dist/web/assets/fira-code-latin-500-normal-B6gioGu8.woff2 +0 -0
  76. package/dist/web/assets/fira-code-latin-500-normal-aMLC2AMm.woff +0 -0
  77. package/dist/web/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
  78. package/dist/web/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
  79. package/dist/web/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
  80. package/dist/web/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
  81. package/dist/web/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
  82. package/dist/web/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
  83. package/dist/web/assets/fira-code-latin-ext-600-normal-0PFQL1eg.woff +0 -0
  84. package/dist/web/assets/fira-code-latin-ext-600-normal-Cb7jxoAi.woff2 +0 -0
  85. package/dist/web/assets/fira-code-symbols2-400-normal-_QEZCEwe.woff +0 -0
  86. package/dist/web/assets/fira-code-symbols2-500-normal-DwsgbIjQ.woff +0 -0
  87. package/dist/web/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
  88. package/dist/web/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNa-Dr0goTwe.woff +0 -0
  89. package/dist/web/assets/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-D-x-0Q06.woff2 +0 -0
  90. package/dist/web/assets/format-SW_H2PBI.js +1 -0
  91. package/dist/web/assets/github-dark-C-LZuMrd.js +1 -0
  92. package/dist/web/assets/github-light-EUqPIrTm.js +1 -0
  93. package/dist/web/assets/go-rLFTqkRN.js +1 -0
  94. package/dist/web/assets/html-BcACZWSP.js +1 -0
  95. package/dist/web/assets/html-DDNsd9lV.js +1 -0
  96. package/dist/web/assets/i18n-RyrLuvXU.js +1 -0
  97. package/dist/web/assets/index-CRwZKCt6.js +2 -0
  98. package/dist/web/assets/index-Fo431P2N.css +1 -0
  99. package/dist/web/assets/init-app-DSQzny_G.js +1 -0
  100. package/dist/web/assets/java-BXcb2rRD.js +1 -0
  101. package/dist/web/assets/javascript-BzbQS41l.js +1 -0
  102. package/dist/web/assets/javascript-Yelw-5ZN.js +1 -0
  103. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  104. package/dist/web/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  105. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  106. package/dist/web/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  107. package/dist/web/assets/jetbrains-mono-cyrillic-600-normal-8K4wrrwR.woff +0 -0
  108. package/dist/web/assets/jetbrains-mono-cyrillic-600-normal-EVf6-Yzo.woff2 +0 -0
  109. package/dist/web/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  110. package/dist/web/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  111. package/dist/web/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  112. package/dist/web/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  113. package/dist/web/assets/jetbrains-mono-greek-600-normal-H7WoG9Et.woff2 +0 -0
  114. package/dist/web/assets/jetbrains-mono-greek-600-normal-mc2nkWzM.woff +0 -0
  115. package/dist/web/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  116. package/dist/web/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  117. package/dist/web/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  118. package/dist/web/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  119. package/dist/web/assets/jetbrains-mono-latin-600-normal-BfsvjouI.woff +0 -0
  120. package/dist/web/assets/jetbrains-mono-latin-600-normal-C8RAYTDA.woff2 +0 -0
  121. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  122. package/dist/web/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  123. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  124. package/dist/web/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  125. package/dist/web/assets/jetbrains-mono-latin-ext-600-normal-BfB_LPfz.woff2 +0 -0
  126. package/dist/web/assets/jetbrains-mono-latin-ext-600-normal-DObL3zCW.woff +0 -0
  127. package/dist/web/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  128. package/dist/web/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  129. package/dist/web/assets/jetbrains-mono-vietnamese-600-normal-OWROknRo.woff +0 -0
  130. package/dist/web/assets/json-B88Oqtu5.js +1 -0
  131. package/dist/web/assets/json-CaljABEy.js +1 -0
  132. package/dist/web/assets/jsx-Bz0zcwM4.js +1 -0
  133. package/dist/web/assets/kotlin-DhhofPvG.js +1 -0
  134. package/dist/web/assets/markdown-BYOwaDjH.js +1 -0
  135. package/dist/web/assets/pinia-BDCzxZ18.js +1 -0
  136. package/dist/web/assets/pinia-BJouyyXU.js +1 -0
  137. package/dist/web/assets/python-gzcpVVnB.js +1 -0
  138. package/dist/web/assets/repository-store-DqnwJIJW.js +1 -0
  139. package/dist/web/assets/runtime-core.esm-bundler-oS9U9Vp7.js +1 -0
  140. package/dist/web/assets/rust-Cfkwpbl8.js +1 -0
  141. package/dist/web/assets/scss-DHtrkMkT.js +1 -0
  142. package/dist/web/assets/syne-greek-400-normal-B4XGRaFa.woff2 +0 -0
  143. package/dist/web/assets/syne-greek-400-normal-C1nzy5ms.woff +0 -0
  144. package/dist/web/assets/syne-greek-500-normal-DUQv5E33.woff2 +0 -0
  145. package/dist/web/assets/syne-greek-500-normal-L1Ji5iNA.woff +0 -0
  146. package/dist/web/assets/syne-greek-600-normal-BJs4kvyH.woff +0 -0
  147. package/dist/web/assets/syne-greek-600-normal-BpFII5Ja.woff2 +0 -0
  148. package/dist/web/assets/syne-greek-700-normal-C01yjWE_.woff +0 -0
  149. package/dist/web/assets/syne-greek-700-normal-RbvlO3f8.woff2 +0 -0
  150. package/dist/web/assets/syne-greek-800-normal-DtzFnRR0.woff +0 -0
  151. package/dist/web/assets/syne-greek-800-normal-n2LZS_yH.woff2 +0 -0
  152. package/dist/web/assets/syne-latin-400-normal-CULFKXub.woff +0 -0
  153. package/dist/web/assets/syne-latin-400-normal-CcHADMBd.woff2 +0 -0
  154. package/dist/web/assets/syne-latin-500-normal-DR6mUQpY.woff +0 -0
  155. package/dist/web/assets/syne-latin-500-normal-emxikWQ7.woff2 +0 -0
  156. package/dist/web/assets/syne-latin-600-normal-BiwQbQXw.woff2 +0 -0
  157. package/dist/web/assets/syne-latin-600-normal-dRu9QuIh.woff +0 -0
  158. package/dist/web/assets/syne-latin-700-normal-AF3Rs61n.woff2 +0 -0
  159. package/dist/web/assets/syne-latin-700-normal-Cd-_iCn5.woff +0 -0
  160. package/dist/web/assets/syne-latin-800-normal-BuJcbPcX.woff +0 -0
  161. package/dist/web/assets/syne-latin-800-normal-EehdNYzx.woff2 +0 -0
  162. package/dist/web/assets/syne-latin-ext-400-normal-B5s6XpS5.woff2 +0 -0
  163. package/dist/web/assets/syne-latin-ext-400-normal-DCnt6qEA.woff +0 -0
  164. package/dist/web/assets/syne-latin-ext-500-normal-C5b4wHnS.woff +0 -0
  165. package/dist/web/assets/syne-latin-ext-500-normal-DHUXVE3f.woff2 +0 -0
  166. package/dist/web/assets/syne-latin-ext-600-normal-DEzBMW8B.woff +0 -0
  167. package/dist/web/assets/syne-latin-ext-600-normal-ZnizrDKU.woff2 +0 -0
  168. package/dist/web/assets/syne-latin-ext-700-normal-C-qCH-vM.woff +0 -0
  169. package/dist/web/assets/syne-latin-ext-700-normal-DuyXglMe.woff2 +0 -0
  170. package/dist/web/assets/syne-latin-ext-800-normal-B2iBRfEf.woff +0 -0
  171. package/dist/web/assets/syne-latin-ext-800-normal-CAQAsWuS.woff2 +0 -0
  172. package/dist/web/assets/theme-DUV6mF_4.js +1 -0
  173. package/dist/web/assets/tsx-udAQXfEw.js +1 -0
  174. package/dist/web/assets/typescript-Utq2Cl8c.js +1 -0
  175. package/dist/web/assets/typescript-j_1H8WHN.js +1 -0
  176. package/dist/web/assets/use-app-theme-DrR0AvTg.js +1 -0
  177. package/dist/web/assets/vue-CSBlZ1UP.js +1 -0
  178. package/dist/web/assets/vue-i18n.runtime-nPdXRlNg.js +3 -0
  179. package/dist/web/assets/wasm-BnjxR4X6.js +1 -0
  180. package/dist/web/assets/yaml-rwi0_p6S.js +1 -0
  181. package/dist/web/favicon.ico +0 -0
  182. package/dist/web/icons/favicon-128x128.png +0 -0
  183. package/dist/web/icons/favicon-16x16.png +0 -0
  184. package/dist/web/icons/favicon-32x32.png +0 -0
  185. package/dist/web/icons/favicon-96x96.png +0 -0
  186. package/dist/web/index.html +5 -0
  187. package/package.json +89 -0
@@ -0,0 +1,71 @@
1
+ import { findReviewById } from "../repositories/review.repo.js";
2
+ import { listCommentsByReview } from "../repositories/comment.repo.js";
3
+ export class ExportNotFoundError extends Error {
4
+ }
5
+ const STATUS_LABELS = {
6
+ in_progress: 'в процессе',
7
+ approved: 'одобрено',
8
+ changes_requested: 'нужны правки'
9
+ };
10
+ function getReviewOrThrow(db, reviewId) {
11
+ const review = findReviewById(db, reviewId);
12
+ if (!review) {
13
+ throw new ExportNotFoundError(`Review ${reviewId} not found`);
14
+ }
15
+ return review;
16
+ }
17
+ export function exportAsJson(db, reviewId) {
18
+ const review = getReviewOrThrow(db, reviewId);
19
+ const comments = listCommentsByReview(db, reviewId);
20
+ return { review, comments };
21
+ }
22
+ function diffLinePrefix(line) {
23
+ if (line.type === 'added')
24
+ return '+';
25
+ if (line.type === 'removed')
26
+ return '-';
27
+ return ' ';
28
+ }
29
+ export function formatReviewAsMarkdown(review, files, comments) {
30
+ const lines = [];
31
+ lines.push(`# Ревью: ${review.repositoryPath}`);
32
+ lines.push('');
33
+ lines.push(`- Источник: ${review.sourceType}${review.sourceRef ? ` (${review.sourceRef})` : ''}`);
34
+ lines.push(`- Статус: ${STATUS_LABELS[review.status]}`);
35
+ lines.push(`- Создано: ${review.createdAt}`);
36
+ lines.push('');
37
+ const commentsByFile = new Map();
38
+ for (const comment of comments) {
39
+ const existing = commentsByFile.get(comment.filePath) ?? [];
40
+ commentsByFile.set(comment.filePath, [...existing, comment]);
41
+ }
42
+ for (const file of files) {
43
+ lines.push(`## ${file.newPath} (+${file.additions}/-${file.deletions})`);
44
+ lines.push('');
45
+ lines.push('```diff');
46
+ for (const hunk of file.hunks) {
47
+ for (const line of hunk.lines) {
48
+ lines.push(`${diffLinePrefix(line)}${line.content}`);
49
+ }
50
+ }
51
+ lines.push('```');
52
+ lines.push('');
53
+ const fileComments = commentsByFile.get(file.newPath) ?? [];
54
+ if (fileComments.length > 0) {
55
+ lines.push('**Комментарии:**');
56
+ lines.push('');
57
+ for (const comment of fileComments) {
58
+ const location = comment.lineNumber !== null ? `Строка ${comment.lineNumber}` : 'Файл';
59
+ lines.push(`- ${location}: ${comment.content}`);
60
+ }
61
+ lines.push('');
62
+ }
63
+ }
64
+ return lines.join('\n');
65
+ }
66
+ export function exportAsMarkdown(db, reviewId) {
67
+ const review = getReviewOrThrow(db, reviewId);
68
+ const comments = listCommentsByReview(db, reviewId);
69
+ const files = JSON.parse(review.snapshotData);
70
+ return formatReviewAsMarkdown(review, files, comments);
71
+ }
@@ -0,0 +1,124 @@
1
+ import { watch, readdirSync, statSync } from 'node:fs';
2
+ import { execFileSync } from 'node:child_process';
3
+ import { join, basename, relative, sep } from 'node:path';
4
+ const IGNORED_DIR_NAMES = new Set([
5
+ 'node_modules',
6
+ '.git',
7
+ 'dist',
8
+ 'build',
9
+ '.venv',
10
+ '.githuman',
11
+ '.cache'
12
+ ]);
13
+ const DEBOUNCE_MS = 300;
14
+ /**
15
+ * Directories git considers fully ignored, one level at a time — i.e. a
16
+ * directory appears here only if *everything* inside it is ignored (a
17
+ * partially-ignored directory still needs walking, for its non-ignored
18
+ * files), matching the granularity `IGNORED_DIR_NAMES` already works at.
19
+ * `git ls-files --directory` collapses such a directory into one entry
20
+ * instead of recursing into it, so this is cheap even for a huge ignored
21
+ * tree like `node_modules`.
22
+ */
23
+ function listGitignoredDirs(repoPath) {
24
+ try {
25
+ const stdout = execFileSync('git', [
26
+ 'ls-files',
27
+ '-z',
28
+ '--others',
29
+ '--ignored',
30
+ '--exclude-standard',
31
+ '--directory'
32
+ ], { cwd: repoPath, encoding: 'utf-8' });
33
+ return new Set(stdout
34
+ .split('\0')
35
+ .filter(entry => entry.endsWith('/'))
36
+ .map(entry => entry.slice(0, -1)));
37
+ }
38
+ catch {
39
+ return new Set(); // Not a git repo, or git isn't available — IGNORED_DIR_NAMES still applies.
40
+ }
41
+ }
42
+ /**
43
+ * Watches a repository's working tree for changes, so the app can tell
44
+ * clients to refresh their diff/file-tree view.
45
+ *
46
+ * Node's `fs.watch(dir, { recursive: true })` registers an OS-level watch on
47
+ * every descendant directory unconditionally, which is prohibitively
48
+ * expensive (and can exceed inotify watch limits) for a tree that includes
49
+ * `node_modules`. This walks the tree itself instead, skipping known-heavy
50
+ * or irrelevant directories, and watches `.git` non-recursively (so changes
51
+ * to `.git/index`/`.git/HEAD` — staging, branch switches — are still picked
52
+ * up without descending into `.git/objects`).
53
+ */
54
+ export function watchRepository(repoPath, onChange, options = {}) {
55
+ const gitignoredDirs = (options.respectGitignore ?? true)
56
+ ? listGitignoredDirs(repoPath)
57
+ : new Set();
58
+ const watchers = [];
59
+ let debounceTimer;
60
+ function isIgnoredDir(path) {
61
+ if (IGNORED_DIR_NAMES.has(basename(path))) {
62
+ return true;
63
+ }
64
+ return gitignoredDirs.has(relative(repoPath, path).split(sep).join('/'));
65
+ }
66
+ function scheduleChange() {
67
+ clearTimeout(debounceTimer);
68
+ debounceTimer = setTimeout(onChange, DEBOUNCE_MS);
69
+ }
70
+ function watchNewEntry(path) {
71
+ let stat;
72
+ try {
73
+ stat = statSync(path);
74
+ }
75
+ catch {
76
+ return; // Already gone (e.g. a rapid create+delete) — nothing to watch.
77
+ }
78
+ if (stat.isDirectory() && !isIgnoredDir(path)) {
79
+ watchDir(path);
80
+ }
81
+ }
82
+ function watchDir(dir) {
83
+ let watcher;
84
+ try {
85
+ watcher = watch(dir, { persistent: false }, (eventType, filename) => {
86
+ scheduleChange();
87
+ if (eventType === 'rename' && filename) {
88
+ watchNewEntry(join(dir, filename));
89
+ }
90
+ });
91
+ }
92
+ catch {
93
+ return; // Directory may have been removed between readdir and watch.
94
+ }
95
+ watchers.push(watcher);
96
+ let entries;
97
+ try {
98
+ entries = readdirSync(dir, { withFileTypes: true });
99
+ }
100
+ catch {
101
+ return;
102
+ }
103
+ for (const entry of entries) {
104
+ const entryPath = join(dir, entry.name);
105
+ if (entry.isDirectory() && !isIgnoredDir(entryPath)) {
106
+ watchDir(entryPath);
107
+ }
108
+ }
109
+ }
110
+ watchDir(repoPath);
111
+ try {
112
+ watchers.push(watch(join(repoPath, '.git'), { persistent: false }, () => scheduleChange()));
113
+ }
114
+ catch {
115
+ // Not a git repo, or .git is missing — nothing more to watch.
116
+ }
117
+ return {
118
+ close: () => {
119
+ clearTimeout(debounceTimer);
120
+ for (const watcher of watchers)
121
+ watcher.close();
122
+ }
123
+ };
124
+ }
@@ -0,0 +1,219 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { basename, resolve, sep } from 'node:path';
5
+ import { simpleGit } from 'simple-git';
6
+ const execFileAsync = promisify(execFile);
7
+ /**
8
+ * Resolves `path` against `repoPath` and rejects anything that escapes the
9
+ * repository root (e.g. `../../etc/passwd`), since `path` here is untrusted
10
+ * input coming straight off the HTTP request.
11
+ */
12
+ function resolveWithinRepo(repoPath, path) {
13
+ const repoRoot = resolve(repoPath);
14
+ const resolved = resolve(repoRoot, path);
15
+ if (resolved !== repoRoot && !resolved.startsWith(repoRoot + sep)) {
16
+ throw new Error(`Path "${path}" escapes the repository root`);
17
+ }
18
+ return resolved;
19
+ }
20
+ /**
21
+ * Rejects a git ref/revision string that could be misparsed as a command
22
+ * option by git itself (e.g. `--output=/etc/passwd` smuggled in as a
23
+ * "branch name"). No real branch, tag, or SHA can start with `-` — git
24
+ * itself refuses to create one (`git branch -- -foo` errors with "not a
25
+ * valid branch name") — so any ref starting with `-` is definitely hostile
26
+ * input, not a legitimate ref a caller could have meant.
27
+ */
28
+ export function assertSafeRef(ref) {
29
+ if (ref.startsWith('-')) {
30
+ throw new Error(`Invalid git ref "${ref}": refs may not start with "-"`);
31
+ }
32
+ }
33
+ /**
34
+ * Reads a file's content at a given git ref.
35
+ *
36
+ * `ref` may be any git ref/SHA, or the literal string 'INDEX' to read the
37
+ * staged (index) version of the file instead of a committed ref.
38
+ *
39
+ * If the path does not exist at that ref (e.g. a newly added file has no
40
+ * HEAD version), returns empty content rather than throwing — the caller
41
+ * treats this as "the file did not exist on this side of the diff".
42
+ */
43
+ export async function getFileAtRef(repoPath, ref, path) {
44
+ if (ref === 'WORKTREE') {
45
+ try {
46
+ const absolutePath = resolveWithinRepo(repoPath, path);
47
+ const buffer = await readFile(absolutePath);
48
+ return {
49
+ content: buffer.includes(0) ? '' : buffer.toString('utf-8'),
50
+ isBinary: buffer.includes(0)
51
+ };
52
+ }
53
+ catch {
54
+ return { content: '', isBinary: false };
55
+ }
56
+ }
57
+ if (ref !== 'INDEX') {
58
+ assertSafeRef(ref);
59
+ }
60
+ const gitRef = ref === 'INDEX' ? `:${path}` : `${ref}:${path}`;
61
+ try {
62
+ // No `--` before gitRef: for the INDEX form (`:path`) it would make git
63
+ // treat the pathspec-looking `:path` as a plain path instead of the
64
+ // special "file staged in the index" syntax, silently changing meaning
65
+ // (falls back to showing HEAD). assertSafeRef above already rules out
66
+ // the injection this would otherwise guard against.
67
+ const { stdout } = await execFileAsync('git', ['show', gitRef], {
68
+ cwd: repoPath,
69
+ encoding: 'buffer',
70
+ maxBuffer: 1024 * 1024 * 100
71
+ });
72
+ const isBinary = stdout.includes(0);
73
+ return {
74
+ content: isBinary ? '' : stdout.toString('utf-8'),
75
+ isBinary
76
+ };
77
+ }
78
+ catch {
79
+ return { content: '', isBinary: false };
80
+ }
81
+ }
82
+ /**
83
+ * Lists every file path visible at a git ref, for browsing the whole
84
+ * codebase rather than just a diff. `'WORKTREE'` lists the working directory
85
+ * (tracked + untracked, honoring .gitignore, matching `getFileAtRef`'s
86
+ * 'WORKTREE' semantics), `'INDEX'` lists the staged snapshot, and any other
87
+ * ref lists that commit's tree.
88
+ */
89
+ export async function getFilesAtRef(repoPath, ref) {
90
+ if (ref === 'WORKTREE') {
91
+ const { stdout } = await execFileAsync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard'], {
92
+ cwd: repoPath,
93
+ encoding: 'utf-8'
94
+ });
95
+ return [...new Set(stdout.split('\0').filter(Boolean))].sort();
96
+ }
97
+ if (ref === 'INDEX') {
98
+ const { stdout } = await execFileAsync('git', ['ls-files', '-z', '--cached'], { cwd: repoPath, encoding: 'utf-8' });
99
+ return stdout.split('\0').filter(Boolean).sort();
100
+ }
101
+ assertSafeRef(ref);
102
+ const { stdout } = await execFileAsync('git', ['ls-tree', '-r', '--name-only', '-z', '--', ref], {
103
+ cwd: repoPath,
104
+ encoding: 'utf-8'
105
+ });
106
+ return stdout.split('\0').filter(Boolean).sort();
107
+ }
108
+ function statusCodeToStatus(code) {
109
+ switch (code[0]) {
110
+ case 'A':
111
+ return 'added';
112
+ case 'D':
113
+ return 'deleted';
114
+ case 'R':
115
+ return 'renamed';
116
+ default:
117
+ return 'modified';
118
+ }
119
+ }
120
+ /**
121
+ * Lists changed paths for a diff, given the git ref arguments that would
122
+ * normally follow `git diff --name-status -M` (e.g. `['--cached']` for
123
+ * staged changes, or `[base, 'HEAD']` for a branch comparison).
124
+ */
125
+ export async function listChangedPaths(repoPath, diffArgs) {
126
+ const { stdout } = await execFileAsync('git', ['diff', '--name-status', '-M', '-z', ...diffArgs], {
127
+ cwd: repoPath,
128
+ encoding: 'utf-8'
129
+ });
130
+ // With -z, git replaces both the record terminator and the inter-field
131
+ // tab with NUL, so the whole output is a flat stream of NUL-separated
132
+ // tokens: <status> <path>, or <status> <oldPath> <newPath> for renames.
133
+ const tokens = stdout.split('\0').filter(token => token !== '');
134
+ const results = [];
135
+ let i = 0;
136
+ while (i < tokens.length) {
137
+ const code = tokens[i++];
138
+ const status = statusCodeToStatus(code);
139
+ if (code[0] === 'R' || code[0] === 'C') {
140
+ const oldPath = tokens[i++];
141
+ const newPath = tokens[i++];
142
+ results.push({ oldPath, newPath, status });
143
+ }
144
+ else {
145
+ const path = tokens[i++];
146
+ results.push({ oldPath: path, newPath: path, status });
147
+ }
148
+ }
149
+ return results;
150
+ }
151
+ /** Lists paths that git has never tracked (respects .gitignore). */
152
+ export async function listUntrackedPaths(repoPath) {
153
+ const { stdout } = await execFileAsync('git', ['ls-files', '-z', '--others', '--exclude-standard'], {
154
+ cwd: repoPath,
155
+ encoding: 'utf-8'
156
+ });
157
+ return stdout.split('\0').filter(path => path !== '');
158
+ }
159
+ /**
160
+ * Stages the given paths (`git add -- <paths>`). With an empty array,
161
+ * stages everything — tracked edits and untracked new files alike
162
+ * (`git add -A`), matching the "Stage all" action in the UI.
163
+ */
164
+ export async function stagePaths(repoPath, paths) {
165
+ const args = paths.length > 0 ? ['add', '--', ...paths] : ['add', '-A'];
166
+ await execFileAsync('git', args, { cwd: repoPath });
167
+ }
168
+ /**
169
+ * Unstages the given paths (`git restore --staged -- <paths>`), leaving
170
+ * their working-tree content untouched. With an empty array, unstages
171
+ * everything, matching `stagePaths`'s "empty = everything" convention.
172
+ */
173
+ export async function unstagePaths(repoPath, paths) {
174
+ const args = paths.length > 0
175
+ ? ['restore', '--staged', '--', ...paths]
176
+ : ['restore', '--staged', '.'];
177
+ await execFileAsync('git', args, { cwd: repoPath });
178
+ }
179
+ /**
180
+ * Discards unstaged working-tree changes for the given paths: an untracked
181
+ * file is deleted outright (`git clean`), a tracked file is restored to its
182
+ * last-staged content (`git restore`). Paths are classified before either
183
+ * git command runs, rather than running `restore` and swallowing a "not
184
+ * found" error for the ones `clean` already removed — `git restore`
185
+ * validates every pathspec up front, so if the batch mixed tracked and
186
+ * untracked paths, an already-removed untracked path would abort the whole
187
+ * call and silently no-op the legitimate tracked restores too.
188
+ */
189
+ export async function discardPaths(repoPath, paths) {
190
+ if (paths.length === 0)
191
+ return;
192
+ const untrackedPaths = new Set(await listUntrackedPaths(repoPath));
193
+ const toClean = paths.filter(path => untrackedPaths.has(path));
194
+ const toRestore = paths.filter(path => !untrackedPaths.has(path));
195
+ if (toClean.length > 0) {
196
+ await execFileAsync('git', ['clean', '-f', '-d', '--', ...toClean], {
197
+ cwd: repoPath
198
+ });
199
+ }
200
+ if (toRestore.length > 0) {
201
+ await execFileAsync('git', ['restore', '--', ...toRestore], {
202
+ cwd: repoPath
203
+ });
204
+ }
205
+ }
206
+ export async function getRepositoryInfo(repoPath) {
207
+ const git = simpleGit(repoPath);
208
+ const [branchSummary, remotes] = await Promise.all([
209
+ git.branch(),
210
+ git.getRemotes(true)
211
+ ]);
212
+ const origin = remotes.find(remote => remote.name === 'origin');
213
+ return {
214
+ name: basename(repoPath),
215
+ branch: branchSummary.current,
216
+ remote: origin?.refs.fetch ?? null,
217
+ path: repoPath
218
+ };
219
+ }
@@ -0,0 +1,71 @@
1
+ import { createReview as insertReview, findReviewById, listReviews, updateReviewStatus as updateReviewStatusRepo, deleteReview as deleteReviewRepo } from "../repositories/review.repo.js";
2
+ import { listCommentsByReview, deleteComment } from "../repositories/comment.repo.js";
3
+ import { getStagedDiff, getUnstagedDiff, getBranchDiff, getCommitsDiff } from "./diff.service.js";
4
+ export class ValidationError extends Error {
5
+ }
6
+ export async function createReview(db, repositoryPath, input, eventBus) {
7
+ const sourceType = input.sourceType ?? 'staged';
8
+ let snapshot;
9
+ let baseRef = null;
10
+ let sourceRef = null;
11
+ if (sourceType === 'staged') {
12
+ snapshot = await getStagedDiff(repositoryPath);
13
+ }
14
+ else if (sourceType === 'unstaged') {
15
+ snapshot = await getUnstagedDiff(repositoryPath);
16
+ }
17
+ else if (sourceType === 'branch') {
18
+ if (!input.baseRef) {
19
+ throw new ValidationError('"baseRef" is required when sourceType is "branch"');
20
+ }
21
+ baseRef = input.baseRef;
22
+ sourceRef = input.sourceRef ?? null;
23
+ snapshot = await getBranchDiff(repositoryPath, input.baseRef);
24
+ }
25
+ else if (sourceType === 'commits') {
26
+ if (!input.baseRef || !input.sourceRef) {
27
+ throw new ValidationError('"baseRef" (from) and "sourceRef" (to) are both required when sourceType is "commits"');
28
+ }
29
+ baseRef = input.baseRef;
30
+ sourceRef = input.sourceRef;
31
+ snapshot = await getCommitsDiff(repositoryPath, input.baseRef, input.sourceRef);
32
+ }
33
+ else {
34
+ throw new ValidationError(`Unknown sourceType: "${String(sourceType)}"`);
35
+ }
36
+ const now = new Date().toISOString();
37
+ const review = {
38
+ id: crypto.randomUUID(),
39
+ repositoryPath,
40
+ baseRef,
41
+ sourceType,
42
+ sourceRef,
43
+ snapshotData: JSON.stringify(snapshot),
44
+ status: 'in_progress',
45
+ createdAt: now,
46
+ updatedAt: now
47
+ };
48
+ const created = insertReview(db, review);
49
+ eventBus?.publish({ type: 'review:created', reviewId: created.id });
50
+ return created;
51
+ }
52
+ export function getReview(db, id) {
53
+ return findReviewById(db, id);
54
+ }
55
+ export function getReviews(db) {
56
+ return listReviews(db);
57
+ }
58
+ export function setReviewStatus(db, id, status, eventBus) {
59
+ const updated = updateReviewStatusRepo(db, id, status);
60
+ if (updated) {
61
+ eventBus?.publish({ type: 'review:updated', reviewId: updated.id });
62
+ }
63
+ return updated;
64
+ }
65
+ export function removeReview(db, id, eventBus) {
66
+ for (const comment of listCommentsByReview(db, id)) {
67
+ deleteComment(db, comment.id);
68
+ }
69
+ deleteReviewRepo(db, id);
70
+ eventBus?.publish({ type: 'review:deleted', reviewId: id });
71
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Shared types between server and web client
3
+ */
4
+ export {};
@@ -0,0 +1 @@
1
+ import{c as e,d as t,j as n,m as r}from"./runtime-core.esm-bundler-oS9U9Vp7.js";import{c as i,q as a}from"./index-CRwZKCt6.js";var o={},s={class:`fullscreen bg-blue text-white text-center q-pa-md flex flex-center`};function c(a,o){return n(),t(`div`,s,[e(`div`,null,[o[0]||=e(`div`,{style:{"font-size":`30vh`}},`404`,-1),o[1]||=e(`div`,{class:`text-h2`,style:{opacity:`0.4`}},`Oops. Nothing here...`,-1),r(i,{class:`q-mt-xl`,color:`white`,"text-color":`blue`,unelevated:``,to:`/`,label:`Go Home`,"no-caps":``})])])}var l=a(o,[[`render`,c]]);export{l as default};
@@ -0,0 +1,3 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/typescript-Utq2Cl8c.js","assets/typescript-j_1H8WHN.js","assets/javascript-Yelw-5ZN.js","assets/javascript-BzbQS41l.js","assets/vue-CSBlZ1UP.js","assets/css-LbU1hoFO.js","assets/html-BcACZWSP.js","assets/json-B88Oqtu5.js","assets/json-CaljABEy.js","assets/css-CdtkT07m.js","assets/scss-DHtrkMkT.js","assets/html-DDNsd9lV.js","assets/core-Ruj7F7dx.js","assets/engine-oniguruma-Bon2Icja.js"])))=>i.map(i=>d[i]);
2
+ import{B as e,C as t,D as n,F as r,H as i,K as a,M as o,N as s,O as c,P as l,Q as u,R as d,S as f,T as p,V as m,X as h,_t as g,b as _,c as v,d as y,g as b,gt as x,h as S,j as C,k as w,l as T,m as E,nt as D,p as O,r as k,s as A,u as j,v as M,vt as N,w as ee,x as te}from"./runtime-core.esm-bundler-oS9U9Vp7.js";import{t as P}from"./create-C46qMo0y.js";import{$ as ne,G as F,J as re,M as ie,U as ae,V as oe,Y as se,_ as I,a as L,b as R,c as z,d as B,et as V,f as H,g as ce,i as le,j as ue,n as U,o as de,p as W,pt as fe,q as G,r as pe,rt as me,s as he,t as K,tt as ge,vt as _e,x as ve,z as ye}from"./index-CRwZKCt6.js";import{n as q}from"./vue-i18n.runtime-nPdXRlNg.js";import{n as be,r as J}from"./pinia-BDCzxZ18.js";import{n as xe,t as Y}from"./client-TNhDHmkt.js";import{a as X,c as Se,i as Z,l as Ce,n as we,o as Te,r as Ee,s as De,t as Oe}from"./format-SW_H2PBI.js";import{t as ke}from"./QPage-DLIDrL1Z.js";function Ae(e){if(e.length<2||e[0]!==`"`||e[e.length-1]!==`"`)return e;let t=e.slice(1,-1),n=[];for(let e=0;e<t.length;e++){let r=t[e];r===`\\`&&/^[0-7]{3}$/.test(t.slice(e+1,e+4))?(n.push(parseInt(t.slice(e+1,e+4),8)),e+=3):r===`\\`&&t[e+1]===`"`?(n.push(34),e+=1):r===`\\`&&t[e+1]===`\\`?(n.push(92),e+=1):n.push((r??``).charCodeAt(0))}return new TextDecoder(`utf-8`).decode(new Uint8Array(n))}function je(e){return{...e,oldPath:Ae(e.oldPath),newPath:Ae(e.newPath)}}function Me(e,t){let n=new Map(e.map(e=>[e.newPath||e.oldPath,e]));return t.map(e=>{let t=n.get(e.newPath||e.oldPath);return t&&JSON.stringify(t)===JSON.stringify(e)?t:e})}var Ne=be(`diff`,()=>{let e=h([]),t=h([]),n=h(!1),r=h(null),i=A(()=>[...e.value,...t.value].map(e=>e.newPath||e.oldPath));async function a(){n.value=!0,r.value=null;try{let[n,r]=await Promise.all([Y(`/api/diff/staged`),Y(`/api/diff/unstaged`)]);e.value=Me(e.value,n.map(je)),t.value=Me(t.value,r.map(je))}catch(n){e.value=[],t.value=[],r.value=n instanceof Error?n.message:String(n)}finally{n.value=!1}}return{stagedFiles:e,unstagedFiles:t,loading:n,error:r,changedPaths:i,fetchDiff:a}});function Pe(e){return e.toSorted((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1).map(e=>({...e,children:e.children?Pe(e.children):void 0}))}function Fe(e,t){let n=[];for(let r of e){let e=r.split(`/`),i=n;for(let n=0;n<e.length;n++){let a=e[n];if(!a)continue;let o=n===e.length-1,s=e.slice(0,n+1).join(`/`),c=i.find(e=>e.name===a);c||(c={name:a,path:s,type:o?`file`:`directory`,isChanged:o?t.has(r):!1,children:o?void 0:[]},i.push(c)),!o&&c.children&&(i=c.children)}}return Pe(n)}function Ie(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=e=>{if(e.type===`file`)return e.path.toLowerCase().includes(n)?e:null;let t=e.children?.map(r).filter(e=>e!==null);return t&&t.length>0?{...e,children:t}:e.name.toLowerCase().includes(n)?e:null};return e.map(r).filter(e=>e!==null)}function Le(){let e=h([]),t=h(!1),n=h(null);async function r(r,i=[]){t.value=!0,n.value=null;try{let t=await Y(`/api/git/tree/${encodeURIComponent(r)}`);e.value=Fe(t.files.map(Ae),new Set(i))}catch(t){n.value=t instanceof Error?t.message:String(t),e.value=[]}finally{t.value=!1}}return{tree:e,loading:t,error:n,fetchTree:r}}function Re(){let e=h([]),t=h(!1),n=h(!1),r=h(null),i=0;async function a(a,o){let s=++i;n.value=!0,r.value=null;try{let n=a.split(`/`).map(encodeURIComponent).join(`/`),r=await Y(`/api/git/file/${n}?ref=${encodeURIComponent(o)}`);if(s!==i)return;e.value=r.lines,t.value=r.isBinary}catch(n){if(s!==i)return;r.value=n instanceof Error?n.message:String(n),e.value=[],t.value=!1}finally{s===i&&(n.value=!1)}}function o(){e.value=[],t.value=!1,r.value=null}return{lines:e,isBinary:t,loading:n,error:r,fetchContent:a,reset:o}}function Q(e){return e.newPath||e.oldPath}function ze(e){return e.type===`file`?e.isChanged:e.children?.some(ze)??!1}var Be=be(`file-explorer`,()=>{let n=Ne(),{tree:r,loading:i,fetchTree:a}=Le(),{lines:o,isBinary:s,loading:c,fetchContent:l,reset:u}=Re(),d=h(`staged`),f=h(!1),p=h(``),m=h(null),g=h(new Set),_=h(new Set),v=A(()=>d.value===`staged`?n.stagedFiles:n.unstagedFiles),y=A(()=>{let e=(p.value??``).trim().toLowerCase();return e?v.value.filter(t=>Q(t).toLowerCase().includes(e)):v.value}),b=A(()=>Ie(r.value,p.value??``)),x=A(()=>{let e=0,t=n=>{for(let r of n)r.type===`file`?e++:r.children&&t(r.children)};return t(r.value),e});e(r,e=>{let t=new Set,n=e=>{for(let r of e)r.type===`directory`&&r.children&&(ze(r)&&t.add(r.path),n(r.children))};n(e),g.value=t},{immediate:!0}),e(f,e=>{p.value=``,m.value=null,e&&a(`WORKTREE`,n.changedPaths)}),e(d,()=>{m.value=null,_.value=new Set}),e(m,e=>{if(f.value){if(!e){u();return}l(e,`WORKTREE`)}});function S(e){let t=new Set(g.value);t.has(e)?t.delete(e):t.add(e),g.value=t}function C(e){let t=new Set(_.value);t.has(e)?t.delete(e):t.add(e),_.value=t}function w(e){m.value=e,C(e)}function T(e){m.value=e,_.value.has(e)||(_.value=new Set(_.value).add(e))}function E(){_.value=new Set(v.value.map(Q))}function D(){_.value=new Set}function O(e){m.value=e,!f.value&&(_.value.has(e)||(_.value=new Set(_.value).add(e)),t(()=>{document.getElementById(`diff-file-${e}`)?.scrollIntoView({block:`nearest`})}))}let k=null,j=0;function M(){return k??=(async()=>{await n.fetchDiff(),f.value&&(await a(`WORKTREE`,n.changedPaths),m.value&&await l(m.value,`WORKTREE`))})().finally(()=>{k=null})}async function N(){j=Date.now(),await M()}async function ee(){Date.now()-j<400||await M()}return{source:d,browseMode:f,filter:p,selectedPath:m,expandedFolders:g,expandedFiles:_,tree:r,treeLoading:i,browseFileLines:o,browseFileIsBinary:s,browseFileLoading:c,diffFiles:v,filteredDiffFiles:y,filteredTree:b,totalTreeFiles:x,toggleFolder:S,toggleFileCard:C,handleCardToggle:w,expandFile:T,expandAllFiles:E,collapseAllFiles:D,selectFile:O,refresh:N,refreshFromServerEvent:ee}});function Ve(e,t){let n=new EventSource(`/api/events`);for(let r of e)n.addEventListener(r,()=>t());return n.addEventListener(`open`,()=>t()),{close:()=>n.close()}}var He=P({name:`QSplitter`,props:{...he,modelValue:{type:Number,required:!0},reverse:Boolean,unit:{type:String,default:`%`,validator:e=>[`%`,`px`].includes(e)},limits:{type:Array,validator:e=>e.length!==2||typeof e[0]!=`number`||typeof e[1]!=`number`?!1:e[0]>=0&&e[0]<=e[1]},emitImmediately:Boolean,horizontal:Boolean,disable:Boolean,beforeClass:[Array,String,Object],afterClass:[Array,String,Object],separatorClass:[Array,String,Object],separatorStyle:[Array,String,Object],separatorAriaLabel:String},emits:[`update:modelValue`],setup(n,{slots:r,emit:a}){let o=ae(),s=de(n,o),c=u(null),l={before:u(null),after:u(null)},d=pe(),f=A(()=>`q-splitter no-wrap ${n.horizontal?`q-splitter--horizontal column`:`q-splitter--vertical row`} q-splitter--${n.disable?`disabled`:`workable`}`+(s()?` q-splitter--dark`:``)),p=A(()=>n.horizontal?`height`:`width`),m=A(()=>n.reverse?`after`:`before`),h=A(()=>n.limits===void 0?n.unit===`%`?[10,90]:[50,1/0]:n.limits);function g(e){return(n.unit===`%`?e:Math.round(e))+n.unit}let _=A(()=>({[m.value]:{[p.value]:g(n.modelValue)}})),v,y,b,x,S;function C(e){if(e.isFirst){let e=c.value.getBoundingClientRect()[p.value];v=n.horizontal?`up`:`left`,y=n.unit===`%`?100:e,b=Math.min(y,h.value[1],Math.max(h.value[0],n.modelValue)),x=(n.reverse?-1:1)*(n.horizontal?1:o.lang.rtl?-1:1)*(n.unit===`%`?e===0?0:100/e:1),c.value.classList.add(`q-splitter--active`);return}if(e.isFinal){S!==n.modelValue&&a(`update:modelValue`,S),c.value.classList.remove(`q-splitter--active`);return}let t=b+x*(e.direction===v?-1:1)*e.distance[n.horizontal?`y`:`x`];S=Math.min(y,h.value[1],Math.max(h.value[0],t)),l[m.value].value.style[p.value]=g(S),n.emitImmediately&&n.modelValue!==S&&a(`update:modelValue`,S)}let w=A(()=>[[we,n.disable?void 0:C,void 0,{[n.horizontal?`vertical`:`horizontal`]:!0,prevent:!0,stop:!0,mouse:!0,mouseAllDir:!0}]]),T=A(()=>{let e={role:`separator`,"aria-orientation":n.horizontal?`horizontal`:`vertical`,"aria-label":n.separatorAriaLabel||o.lang.label.resize};if(n.disable)e[`aria-disabled`]=`true`;else{let t=h.value;e.tabindex=0,e[`aria-controls`]=d.value,e[`aria-valuemin`]=t[0],t[1]!==1/0&&(e[`aria-valuemax`]=t[1]),e[`aria-valuenow`]=Math.round(n.modelValue*100)/100}return e}),E=null;function D(e){let{keyCode:t}=e,r=n.horizontal?[38,40]:[37,39];if(t!==13&&t!==36&&t!==35&&!r.includes(t))return;fe(e);let i=h.value,s=n.unit===`%`?100:c.value.getBoundingClientRect()[p.value],l;if(t===13)n.modelValue===i[0]?l=E===null?n.modelValue:E:(E=n.modelValue,l=i[0]);else if(t===36)l=i[0];else if(t===35)l=i[1];else{let e=(t===r[0]?-1:1)*(n.reverse?-1:1)*(n.horizontal?1:o.lang.rtl?-1:1);l=n.modelValue+e*(n.unit===`%`?1:10)}let u=Math.min(s,i[1],Math.max(i[0],l));u!==n.modelValue&&a(`update:modelValue`,u)}function O(e,t){e<t[0]?a(`update:modelValue`,t[0]):e>t[1]&&a(`update:modelValue`,t[1])}return e(()=>n.modelValue,e=>{O(e,h.value)}),e(()=>n.limits,()=>{t(()=>{O(n.modelValue,h.value)})}),()=>{let e=[M(`div`,{ref:l.before,id:m.value===`before`?d.value:void 0,class:[`q-splitter__panel q-splitter__before`+(n.reverse?` col`:``),n.beforeClass],style:_.value.before},ve(r.before)),M(`div`,{class:[`q-splitter__separator`,n.separatorClass],style:n.separatorStyle,...T.value,onKeydown:n.disable?void 0:D},[i(M(`div`,{class:`q-splitter__separator-area absolute-full`},ve(r.separator)),w.value)]),M(`div`,{ref:l.after,id:m.value===`after`?d.value:void 0,class:[`q-splitter__panel q-splitter__after`+(n.reverse?``:` col`),n.afterClass],style:_.value.after},ve(r.after))];return M(`div`,{class:f.value,ref:c},R(r.default,e))}}}),Ue=260,We=220,Ge=600,Ke=G(S({__name:`PanelResize`,setup(e){let t=h(Ue),n=A(()=>[We,Ge]);return(e,r)=>(C(),T(He,{modelValue:t.value,"onUpdate:modelValue":r[0]||=e=>t.value=e,limits:n.value,unit:`px`,class:`file-explorer`,"before-class":`file-explorer__panel`,"after-class":`file-explorer__content`},{before:m(()=>[l(e.$slots,`panel`,{},void 0,!0)]),after:m(()=>[l(e.$slots,`content`,{},void 0,!0)]),_:3},8,[`modelValue`,`limits`]))}}),[[`__scopeId`,`data-v-1ce1b104`]]),qe=P({props:[`store`,`barStyle`,`verticalBarStyle`,`horizontalBarStyle`],setup(e){return()=>[M(`div`,{class:e.store.scroll.vertical.barClass.value,style:[e.barStyle,e.verticalBarStyle],"aria-hidden":`true`,onMousedown:e.store.onVerticalMousedown}),M(`div`,{class:e.store.scroll.horizontal.barClass.value,style:[e.barStyle,e.horizontalBarStyle],"aria-hidden":`true`,onMousedown:e.store.onHorizontalMousedown}),i(M(`div`,{ref:e.store.scroll.vertical.ref,class:e.store.scroll.vertical.thumbClass.value,style:e.store.scroll.vertical.style.value,"aria-hidden":`true`}),e.store.thumbVertDir),i(M(`div`,{ref:e.store.scroll.horizontal.ref,class:e.store.scroll.horizontal.thumbClass.value,style:e.store.scroll.horizontal.style.value,"aria-hidden":`true`}),e.store.thumbHorizDir)]}}),Je=[`vertical`,`horizontal`],Ye={vertical:{offset:`offsetY`,scroll:`scrollTop`,dir:`down`,dist:`y`},horizontal:{offset:`offsetX`,scroll:`scrollLeft`,dir:`right`,dist:`x`}},Xe={prevent:!0,mouse:!0,mouseAllDir:!0},Ze=e=>e>=250?50:Math.ceil(e/5),$=(e,t)=>t?-e:e;function Qe(e,t){return Je.includes(e)?!0:(console.error(`[QScrollArea]: wrong first param of ${t} (vertical/horizontal)`),!1)}var $e=P({name:`QScrollArea`,props:{...he,thumbStyle:Object,verticalThumbStyle:Object,horizontalThumbStyle:Object,barStyle:[Array,String,Object],verticalBarStyle:[Array,String,Object],horizontalBarStyle:[Array,String,Object],verticalOffset:{type:Array,default:()=>[0,0]},horizontalOffset:{type:Array,default:()=>[0,0]},contentStyle:[Array,String,Object],contentActiveStyle:[Array,String,Object],delay:{type:[String,Number],default:1e3},visible:{type:Boolean,default:null},tabindex:[String,Number],onScroll:Function},setup(t,{slots:r,emit:i}){let a=h(!1),o=h(!1),s=h(!1),c={vertical:h(0),horizontal:h(0)},l={vertical:{ref:u(null),position:h(0),size:h(0)},horizontal:{ref:u(null),position:h(0),size:h(0)}},{proxy:d}=b(),f=ae(),m=de(t,f),g=null,_,v=u(null),y=A(()=>`q-scrollarea`+(m()?` q-scrollarea--dark`:``));Object.assign(c,{verticalInner:A(()=>c.vertical.value-t.verticalOffset[0]-t.verticalOffset[1]),horizontalInner:A(()=>c.horizontal.value-t.horizontalOffset[0]-t.horizontalOffset[1])}),l.vertical.percentage=A(()=>{let e=l.vertical.size.value-c.vertical.value;if(e<=0)return 0;let t=Oe(l.vertical.position.value/e,0,1);return Math.round(t*1e4)/1e4}),l.vertical.thumbHidden=A(()=>!(t.visible===null?s.value:t.visible)&&!a.value&&!o.value||l.vertical.size.value<=c.vertical.value+1),l.vertical.thumbStart=A(()=>t.verticalOffset[0]+l.vertical.percentage.value*(c.verticalInner.value-l.vertical.thumbSize.value)),l.vertical.thumbSize=A(()=>Math.round(Oe(c.verticalInner.value*c.verticalInner.value/l.vertical.size.value,Ze(c.verticalInner.value),c.verticalInner.value))),l.vertical.style=A(()=>({...t.thumbStyle,...t.verticalThumbStyle,top:`${l.vertical.thumbStart.value}px`,height:`${l.vertical.thumbSize.value}px`,[f.lang.rtl?`left`:`right`]:`${t.horizontalOffset[+!f.lang.rtl]}px`})),l.vertical.thumbClass=A(()=>`q-scrollarea__thumb q-scrollarea__thumb--v absolute-right`+(l.vertical.thumbHidden.value?` q-scrollarea__thumb--invisible`:``)),l.vertical.barClass=A(()=>`q-scrollarea__bar q-scrollarea__bar--v absolute-right`+(l.vertical.thumbHidden.value?` q-scrollarea__bar--invisible`:``)),l.horizontal.percentage=A(()=>{let e=l.horizontal.size.value-c.horizontal.value;if(e<=0)return 0;let t=Oe($(l.horizontal.position.value,f.lang.rtl)/e,0,1);return Math.round(t*1e4)/1e4}),l.horizontal.thumbHidden=A(()=>!(t.visible===null?s.value:t.visible)&&!a.value&&!o.value||l.horizontal.size.value<=c.horizontal.value+1),l.horizontal.thumbStart=A(()=>t.horizontalOffset[+!!f.lang.rtl]+l.horizontal.percentage.value*(c.horizontalInner.value-l.horizontal.thumbSize.value)),l.horizontal.thumbSize=A(()=>Math.round(Oe(c.horizontalInner.value*c.horizontalInner.value/l.horizontal.size.value,Ze(c.horizontalInner.value),c.horizontalInner.value))),l.horizontal.style=A(()=>({...t.thumbStyle,...t.horizontalThumbStyle,[f.lang.rtl?`right`:`left`]:`${l.horizontal.thumbStart.value}px`,width:`${l.horizontal.thumbSize.value}px`,bottom:`${t.verticalOffset[1]}px`})),l.horizontal.thumbClass=A(()=>`q-scrollarea__thumb q-scrollarea__thumb--h absolute-bottom`+(l.horizontal.thumbHidden.value?` q-scrollarea__thumb--invisible`:``)),l.horizontal.barClass=A(()=>`q-scrollarea__bar q-scrollarea__bar--h absolute-bottom`+(l.horizontal.thumbHidden.value?` q-scrollarea__bar--invisible`:``));let x=A(()=>t.tabindex===void 0?l.vertical.size.value>c.vertical.value+1||l.horizontal.size.value>c.horizontal.value+1?0:void 0:t.tabindex),S=A(()=>l.vertical.thumbHidden.value&&l.horizontal.thumbHidden.value?t.contentStyle:t.contentActiveStyle);function C(){return{verticalPosition:l.vertical.position.value,verticalPercentage:l.vertical.percentage.value,verticalSize:l.vertical.size.value,verticalContainerSize:c.vertical.value,verticalContainerInnerSize:c.verticalInner.value,horizontalPosition:l.horizontal.position.value,horizontalPercentage:l.horizontal.percentage.value,horizontalSize:l.horizontal.size.value,horizontalContainerSize:c.horizontal.value,horizontalContainerInnerSize:c.horizontalInner.value}}let w=me(()=>{let e=C();e.ref=d,i(`scroll`,e)},0);function T(e,t,n){Qe(e,`setScrollPosition`)&&(e===`vertical`?ie:ue)(v.value,t,n)}function E({height:e,width:t}){let n=!1;c.vertical.value!==e&&(c.vertical.value=e,n=!0),c.horizontal.value!==t&&(c.horizontal.value=t,n=!0),n&&N()}function D({position:e}){let t=!1;l.vertical.position.value!==e.top&&(l.vertical.position.value=e.top,t=!0),l.horizontal.position.value!==e.left&&(l.horizontal.position.value=e.left,t=!0),t&&N()}function O({height:e,width:t}){l.horizontal.size.value!==t&&(l.horizontal.size.value=t,N()),l.vertical.size.value!==e&&(l.vertical.size.value=e,N())}function k(e,t){let n=l[t];if(e.isFirst){if(n.thumbHidden.value)return;_=t===`horizontal`?$(n.position.value,f.lang.rtl):n.position.value,o.value=!0}else if(!o.value)return;e.isFinal&&(o.value=!1);let r=Ye[t],i=(n.size.value-c[t].value)/(c[t+`Inner`].value-n.thumbSize.value),a=e.distance[r.dist],s=(e.direction===r.dir?1:-1)*(t===`horizontal`&&f.lang.rtl?-1:1),u=_+s*a*i;te(t===`horizontal`?$(u,f.lang.rtl):u,t)}function j(e,n){let r=l[n];if(!r.thumbHidden.value){let i=n===`horizontal`&&f.lang.rtl,a=n===`vertical`?t.verticalOffset[0]:t.horizontalOffset[+!!i],o=(i?c.horizontal.value-e.offsetX:e[Ye[n].offset])-a,s=r.thumbStart.value-a;if(o<s||o>s+r.thumbSize.value){let e=o-r.thumbSize.value/2,t=Oe(e/(c[n+`Inner`].value-r.thumbSize.value),0,1);te(i?$(t*Math.max(0,r.size.value-c[n].value),f.lang.rtl):t*Math.max(0,r.size.value-c[n].value),n)}r.ref.value!==null&&r.ref.value.dispatchEvent(new MouseEvent(e.type,e))}}function N(){a.value=!0,g!==null&&clearTimeout(g),g=setTimeout(()=>{g=null,a.value=!1},t.delay),t.onScroll!==void 0&&w()}function te(e,t){v.value[Ye[t].scroll]=e}let P=null;function ne(){P!==null&&clearTimeout(P),P=setTimeout(()=>{P=null,s.value=!0},f.platform.is.ios?50:0)}function F(){P!==null&&(clearTimeout(P),P=null),s.value=!1}let re=null;e(()=>f.lang.rtl,(e,t)=>{v.value!==null&&ue(v.value,$($(l.horizontal.position.value,t),e))}),n(()=>{re={top:l.vertical.position.value,left:l.horizontal.position.value}}),ee(()=>{if(re===null)return;let e=v.value;e!==null&&(ue(e,re.left),ie(e,re.top))}),p(w.cancel),Object.assign(d,{getScrollTarget:()=>v.value,getScroll:C,getScrollPosition:()=>({top:l.vertical.position.value,left:l.horizontal.position.value}),getScrollPercentage:()=>({top:l.vertical.percentage.value,left:l.horizontal.percentage.value}),setScrollPosition:T,setScrollPercentage(e,t,n){if(!Qe(e,`setScrollPercentage`))return;let r=t*(l[e].size.value-c[e].value);T(e,e===`horizontal`?$(r,f.lang.rtl):r,n)}});let oe={scroll:l,thumbVertDir:[[we,e=>{k(e,`vertical`)},void 0,{vertical:!0,...Xe}]],thumbHorizDir:[[we,e=>{k(e,`horizontal`)},void 0,{horizontal:!0,...Xe}]],onVerticalMousedown(e){j(e,`vertical`)},onHorizontalMousedown(e){j(e,`horizontal`)}};return()=>M(`div`,{class:y.value,onMouseenter:ne,onMouseleave:F},[M(`div`,{ref:v,class:`q-scrollarea__container scroll relative-position fit hide-scrollbar`,tabindex:x.value},[M(`div`,{class:`q-scrollarea__content absolute`,style:S.value},R(r.default,[M(Se,{debounce:0,onResize:O})])),M(Ce,{axis:`both`,onScroll:D})]),M(Se,{debounce:0,onResize:E}),M(qe,{store:oe,barStyle:t.barStyle,verticalBarStyle:t.verticalBarStyle,horizontalBarStyle:t.horizontalBarStyle})])}}),et=0,tt=[`click`,`keydown`],nt={icon:String,label:[Number,String],alert:[Boolean,String],alertIcon:String,name:{type:[Number,String],default:()=>`t_${et++}`},noCaps:Boolean,tabindex:[String,Number],disable:Boolean,contentClass:String,ripple:{type:[Boolean,Object],default:!0}},rt=[13,32];function it(e,t,n,r){let a=_(ne,se);if(a===se)return console.error(`QTab/QRouteTab component needs to be child of QTabs`),se;let{proxy:o}=b(),s=u(null),l=u(null),d=u(null);function f(){return e.disable||e.ripple===!1?!1:{keyCodes:rt,early:!0,...e.ripple===!0?{}:e.ripple}}function m(t){let n=a.tabProps.value;return`q-tab relative-position self-stretch flex flex-center text-center`+(t?` q-tab--active`+(n.activeClass?` `+n.activeClass:``)+(n.activeColor?` text-${n.activeColor}`:``)+(n.activeBgColor?` bg-${n.activeBgColor}`:``):` q-tab--inactive`)+(e.icon&&e.label&&!n.inlineLabel?` q-tab--full`:``)+(e.noCaps||n.noCaps?` q-tab--no-caps`:``)+(e.disable?` disabled`:` q-focusable q-hoverable cursor-pointer`)+(r===void 0?``:r.linkClass.value)}function h(){return`q-tab__content self-stretch flex-center relative-position q-anchor--skip non-selectable `+(a.tabProps.value.inlineLabel?`row no-wrap q-tab__content--inline`:`column`)+(e.contentClass===void 0?``:` ${e.contentClass}`)}let g=A(()=>a.currentModel.value===e.name),v=A(()=>{if(e.disable||a.hasFocus.value)return-1;let t=a.tabStopName.value;return t===null||t===e.name?e.tabindex||0:-1});function y(t,i){if(!i&&!t?.qAvoidFocus&&s.value?.focus({preventScroll:!0}),e.disable){r?.hasRouterLink.value===!0&&fe(t);return}if(r===void 0){a.updateModel({name:e.name}),n(`click`,t);return}if(r.hasRouterLink.value){let i=(n={})=>{let i,o=n.to===void 0||re(n.to,e.to)?a.avoidRouteWatcher=le():null;return r.navigateToRouterLink(t,{...n,returnRouterError:!0}).catch(e=>{i=e}).then(t=>{if(o===a.avoidRouteWatcher&&(a.avoidRouteWatcher=!1,i===void 0&&(t===void 0||t.message?.startsWith(`Avoided redundant navigation`)===!0)&&a.updateModel({name:e.name})),n.returnRouterError)return i===void 0?t:Promise.reject(i)})};n(`click`,t,i),t.defaultPrevented||i();return}n(`click`,t)}function x(e){n(`keydown`,e),!e.defaultPrevented&&(V(e,[13,32])?y(e,!0):e.keyCode>=35&&e.keyCode<=40&&!e.altKey&&!e.metaKey&&!ge(e)&&a.onKbdNavigate(e.keyCode,o.$el)&&fe(e))}function S(){let n=a.tabProps.value,r=n.narrowIndicator,i=[],o=M(`div`,{ref:d,class:[`q-tab__indicator`,n.indicatorClass]});e.icon!==void 0&&i.push(M(W,{class:`q-tab__icon`,name:e.icon})),e.label!==void 0&&i.push(M(`div`,{class:`q-tab__label`},e.label)),e.alert&&i.push(e.alertIcon===void 0?M(`div`,{class:`q-tab__alert`+(e.alert===!0?``:` text-${e.alert}`)}):M(W,{class:`q-tab__alert-icon`,color:e.alert===!0?void 0:e.alert,name:e.alertIcon})),r&&i.push(o);let c=[M(`div`,{class:`q-focus-helper`,tabindex:-1,ref:s}),M(`div`,{class:h()},R(t.default,i))];return r||c.push(o),c}let C={name:A(()=>e.name),disable:A(()=>e.disable),rootRef:l,tabIndicatorRef:d,routeData:r};p(()=>{a.unregisterTab(C)}),c(()=>{a.registerTab(C)});function w(t,n){let r={ref:l,class:m(g.value),tabindex:v.value,role:`tab`,"aria-selected":g.value?`true`:`false`,"aria-disabled":e.disable?`true`:void 0,onClick:y,onKeydown:x,...n};return i(M(t,r,S()),[[B,f()]])}return{renderTab:w,$tabs:a}}var at=P({name:`QTab`,props:nt,emits:tt,setup(e,{slots:t,emit:n}){let{renderTab:r}=it(e,t,n);return()=>r(`div`)}});function ot(e,t,n){let r=n?[`left`,`right`]:[`top`,`bottom`];return`absolute-${t?r[0]:r[1]}${e?` text-${e}`:``}`}function st(e,t){for(let n in e)if(e[n]!==t[n])return!1;return!0}var ct=[`left`,`center`,`right`,`justify`],lt=P({name:`QTabs`,props:{modelValue:[Number,String],align:{type:String,default:`center`,validator:e=>ct.includes(e)},breakpoint:{type:[String,Number],default:600},vertical:Boolean,shrink:Boolean,stretch:Boolean,activeClass:String,activeColor:String,activeBgColor:String,indicatorColor:String,leftIcon:String,rightIcon:String,outsideArrows:Boolean,mobileArrows:Boolean,switchIndicator:Boolean,narrowIndicator:Boolean,inlineLabel:Boolean,noCaps:Boolean,dense:Boolean,contentClass:String,"onUpdate:modelValue":[Function,Array]},setup(t,{slots:r,emit:i}){let{proxy:a}=b(),s=ae(),{registerTick:c}=ye(),{registerTick:l}=ye(),{registerTick:d}=ye(),{registerTimeout:f,removeTimeout:m}=oe(),{registerTimeout:g,removeTimeout:_}=oe(),v=u(null),y=u(null),x=h(t.modelValue),S=h(!1),C=h(!0),w=h(!1),T=h(!1),E=[],D=h(0),O=h(!1),k=null,j=null,N,te=A(()=>({activeClass:t.activeClass,activeColor:t.activeColor,activeBgColor:t.activeBgColor,indicatorClass:ot(t.indicatorColor,t.switchIndicator,t.vertical),narrowIndicator:t.narrowIndicator,inlineLabel:t.inlineLabel,noCaps:t.noCaps})),P=A(()=>{let e=D.value,t=x.value,n=null;for(let r=0;r<e;r++){let e=E[r];if(!e.disable.value){if(e.name.value===t)return t;n===null&&(n=e.name.value)}}return n}),F=A(()=>`q-tabs__content--align-${S.value?`left`:T.value?`justify`:t.align}`),re=A(()=>`q-tabs row no-wrap items-center q-tabs--${S.value?``:`not-`}scrollable q-tabs--${t.vertical?`vertical`:`horizontal`} q-tabs__arrows--${t.outsideArrows?`outside`:`inside`} q-tabs--mobile-with${t.mobileArrows?``:`out`}-arrows`+(t.dense?` q-tabs--dense`:``)+(t.shrink?` col-shrink`:``)+(t.stretch?` self-stretch`:``)),ie=A(()=>`q-tabs__content row no-wrap items-center self-stretch hide-scrollbar relative-position `+F.value+(t.contentClass===void 0?``:` ${t.contentClass}`)),se=A(()=>t.vertical?`height`:`width`),I=A(()=>!t.vertical&&s.lang.rtl===!0);e(I,H),e(()=>t.modelValue,e=>{L({name:e,setCurrent:!0,skipEmit:!0})}),e(()=>t.outsideArrows,R);function L({name:e,setCurrent:n,skipEmit:r}){x.value!==e&&(!r&&t[`onUpdate:modelValue`]!==void 0&&i(`update:modelValue`,e),(n||t[`onUpdate:modelValue`]===void 0)&&(B(x.value,e),x.value=e))}function R(){c(()=>{v.value&&z({width:v.value.offsetWidth,height:v.value.offsetHeight})})}function z(e){if(y.value===null)return;let n=e[se.value],r=Array.prototype.reduce.call(y.value.children,(e,t)=>e+t.getBoundingClientRect()[se.value],0),i=n>0&&r-n>1;S.value=i,i&&l(H),T.value=n<Number.parseInt(t.breakpoint,10)}function B(e,n){let r=e!=null&&e!==``?E.find(t=>t.name.value===e):null,i=n!=null&&n!==``?E.find(e=>e.name.value===n):null;if(Y)Y=!1;else if(r&&i){let e=r.tabIndicatorRef.value,n=i.tabIndicatorRef.value;k!==null&&(clearTimeout(k),k=null),e.style.transition=`none`,e.style.transform=`none`,n.style.transition=`none`,n.style.transform=`none`;let a=e.getBoundingClientRect(),o=n.getBoundingClientRect();n.style.transform=t.vertical?`translate3d(0,${a.top-o.top}px,0) scale3d(1,${o.height?a.height/o.height:1},1)`:`translate3d(${a.left-o.left}px,0,0) scale3d(${o.width?a.width/o.width:1},1,1)`,d(()=>{k=setTimeout(()=>{k=null,n.style.transition=`transform .25s cubic-bezier(.4, 0, .2, 1)`,n.style.transform=`none`},70)})}i&&S.value&&V(i.rootRef.value)}function V(e){let{left:n,width:r,top:i,height:a}=y.value.getBoundingClientRect(),o=e.getBoundingClientRect(),s=t.vertical?o.top-i:o.left-n;if(s<0){y.value[t.vertical?`scrollTop`:`scrollLeft`]+=Math.floor(s),H();return}s+=t.vertical?o.height-a:o.width-r,s>0&&(y.value[t.vertical?`scrollTop`:`scrollLeft`]+=Math.ceil(s),H())}function H(){let e=y.value;if(e===null)return;let n=e.getBoundingClientRect(),r=t.vertical?e.scrollTop:Math.abs(e.scrollLeft);I.value?(C.value=Math.ceil(r+n.width)<e.scrollWidth-1,w.value=r>0):(C.value=r>0,w.value=t.vertical?Math.ceil(r+n.height)<e.scrollHeight:Math.ceil(r+n.width)<e.scrollWidth)}function ce(e){j!==null&&clearInterval(j),j=setInterval(()=>{G(e)&&U()},5)}function le(){ce(I.value?2**53-1:0)}function ue(){ce(I.value?0:2**53-1)}function U(){j!==null&&(clearInterval(j),j=null)}function de(e,n){let r=Array.prototype.filter.call(y.value.children,e=>e===n||e.matches?.(`.q-tab.q-focusable`)),i=r.length;if(i===0)return;if(e===36)return V(r[0]),r[0].focus(),!0;if(e===35)return V(r[i-1]),r[i-1].focus(),!0;let a=e===(t.vertical?38:37),o=e===(t.vertical?40:39),s=a?-1:o?1:void 0;if(s!==void 0){let e=t.vertical!==!0&&I.value?-1:1,a=(r.indexOf(n)+s*e+i)%i;return V(r[a]),r[a].focus({preventScroll:!0}),!0}}let fe=A(()=>I.value?{get:e=>Math.abs(e.scrollLeft),set:(e,t)=>{e.scrollLeft=-t}}:t.vertical?{get:e=>e.scrollTop,set:(e,t)=>{e.scrollTop=t}}:{get:e=>e.scrollLeft,set:(e,t)=>{e.scrollLeft=t}});function G(e){let t=y.value,{get:n,set:r}=fe.value,i=!1,a=n(t),o=e<a?-1:1;return a+=o*5,a<0?(i=!0,a=0):(o===-1&&a<=e||o===1&&a>=e)&&(i=!0,a=e),r(t,a),H(),i}function pe(){let e=null,t={matchedLen:0,queryDiff:9999,hrefLen:0},n=E.filter(e=>e.routeData?.hasRouterLink.value===!0),{hash:r,query:i}=a.$route,o=Object.keys(i).length;for(let a of n){let n=a.routeData.exact.value===!0;if(!a.routeData[n?`linkIsExactActive`:`linkIsActive`].value)continue;let{hash:s,query:c,matched:l,href:u}=a.routeData.resolvedLink.value,d=Object.keys(c).length;if(n){if(s!==r||d!==o||!st(i,c))continue;e=a.name.value;break}if(s!==``&&s!==r||d!==0&&!st(c,i))continue;let f={matchedLen:l.length,queryDiff:o-d,hrefLen:u.length-s.length};if(f.matchedLen>t.matchedLen){e=a.name.value,t=f;continue}if(f.matchedLen===t.matchedLen){if(f.queryDiff<t.queryDiff)e=a.name.value,t=f;else if(f.queryDiff!==t.queryDiff)continue;f.hrefLen>t.hrefLen&&(e=a.name.value,t=f)}}if(e===null&&E.some(e=>e.routeData===void 0&&e.name.value===x.value)){Y=!1;return}L({name:e,setCurrent:!0})}function me(e){if(m(),!O.value&&v.value!==null&&e.target&&typeof e.target.closest==`function`){let t=e.target.closest(`.q-tab`);t&&v.value.contains(t)&&(O.value=!0,S.value&&V(t))}}function he(){f(()=>{O.value=!1},30)}function K(){be.avoidRouteWatcher===!1?g(pe):_()}function ge(){if(N===void 0){let t=e(()=>a.$route.fullPath,K);N=()=>{t(),N=void 0}}}function _e(e){E.push(e),D.value++,R(),e.routeData===void 0||a.$route===void 0?g(()=>{if(S.value){let e=x.value,t=e!=null&&e!==``?E.find(t=>t.name.value===e):null;t&&V(t.rootRef.value)}}):(ge(),e.routeData.hasRouterLink.value&&K())}function q(e){E.splice(E.indexOf(e),1),D.value--,R(),N!==void 0&&e.routeData!==void 0&&(E.every(e=>e.routeData===void 0)&&N(),K())}let be={currentModel:x,tabProps:te,hasFocus:O,tabStopName:P,registerTab:_e,unregisterTab:q,verifyRouteModel:K,updateModel:L,onKbdNavigate:de,avoidRouteWatcher:!1};o(ne,be);function J(){k!==null&&clearTimeout(k),U(),N?.()}let xe=!1,Y=!1;return p(J),n(()=>{xe=N!==void 0,J()}),ee(()=>{xe&&(ge(),Y=!0,K()),R()}),()=>M(`div`,{ref:v,class:re.value,role:`tablist`,"aria-orientation":t.vertical?`vertical`:`horizontal`,onFocusin:me,onFocusout:he},[M(Se,{onResize:z}),M(`div`,{ref:y,class:ie.value,onScroll:H},ve(r.default)),M(W,{class:`q-tabs__arrow q-tabs__arrow--left absolute q-tab__icon`+(C.value?``:` q-tabs__arrow--faded`),name:t.leftIcon||s.iconSet.tabs[t.vertical?`up`:`left`],onMousedownPassive:le,onTouchstartPassive:le,onMouseupPassive:U,onMouseleavePassive:U,onTouchendPassive:U}),M(W,{class:`q-tabs__arrow q-tabs__arrow--right absolute q-tab__icon`+(w.value?``:` q-tabs__arrow--faded`),name:t.rightIcon||s.iconSet.tabs[t.vertical?`down`:`right`],onMousedownPassive:ue,onTouchstartPassive:ue,onMouseupPassive:U,onMouseleavePassive:U,onTouchendPassive:U})])}}),ut={class:`row items-center no-wrap q-gutter-x-xs`},dt={class:`row items-center no-wrap q-gutter-x-xs`},ft=S({__name:`FileExplorerTabs`,props:te({stagedFilesLength:{},unstagedFilesLength:{}},{modelValue:{default:`staged`},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=d(e,`modelValue`),{t:n}=q();return(r,i)=>(C(),T(lt,{modelValue:t.value,"onUpdate:modelValue":i[0]||=e=>t.value=e,dense:``,"no-caps":``,align:`left`,"narrow-indicator":``,class:`text-primary q-mb-sm`},{default:m(()=>[E(at,{name:`staged`},{default:m(()=>[v(`div`,ut,[v(`span`,null,N(D(n)(`changes.staged`)),1),E(De,{color:`positive`,rounded:``},{default:m(()=>[O(N(e.stagedFilesLength),1)]),_:1})])]),_:1}),E(at,{name:`unstaged`},{default:m(()=>[v(`div`,dt,[v(`span`,null,N(D(n)(`changes.unstaged`)),1),E(De,{color:`warning`,rounded:``},{default:m(()=>[O(N(e.unstagedFilesLength),1)]),_:1})])]),_:1})]),_:1},8,[`modelValue`]))}}),pt=S({__name:`SearchInput`,props:{modelValue:{},modelModifiers:{}},emits:[`update:modelValue`],setup(e){let t=d(e,`modelValue`);return(e,n)=>(C(),T(U,f({modelValue:t.value,"onUpdate:modelValue":n[0]||=e=>t.value=e},e.$attrs,{dense:``,outlined:``,clearable:``}),{prepend:m(()=>[E(W,{name:`search`,size:`xs`})]),_:1},16,[`modelValue`]))}}),mt={class:`file-tree-node`},ht={class:`row items-center no-wrap q-gutter-x-xs`},gt={class:`ellipsis file-tree-node__label`},_t={class:`ellipsis file-tree-node__label`},vt={key:2},yt=G(S({__name:`FileTreeNode`,props:{node:{},selectedPath:{},expandedFolders:{},level:{}},emits:[`toggle-folder`,`file-select`],setup(e,{emit:t}){let n=e,a=t,o=8+n.level*12;return(t,n)=>{let c=r(`FileTreeNode`,!0);return C(),y(`div`,mt,[e.node.type===`directory`?i((C(),T(Ee,{key:0,clickable:``,dense:``,style:g({paddingLeft:`${o}px`}),onClick:n[0]||=t=>a(`toggle-folder`,e.node.path)},{default:m(()=>[E(Z,{avatar:``,class:`file-tree-node__icon-section`},{default:m(()=>[v(`div`,ht,[E(W,{name:`chevron_right`,size:`xs`,class:x([`file-tree-node__chevron`,{"file-tree-node__chevron--expanded":e.expandedFolders.has(e.node.path)}])},null,8,[`class`]),E(W,{name:e.expandedFolders.has(e.node.path)?`folder_open`:`folder`,size:`xs`,color:`warning`},null,8,[`name`])])]),_:1}),E(Z,{class:`text-mono`},{default:m(()=>[v(`div`,gt,[O(N(e.node.name)+` `,1),E(X,{anchor:`top middle`,self:`bottom middle`},{default:m(()=>[O(N(e.node.path),1)]),_:1})])]),_:1}),e.node.children?(C(),T(Z,{key:0,side:``,class:`text-caption text-grey-6`},{default:m(()=>[O(N(e.node.children.length),1)]),_:1})):j(``,!0)]),_:1},8,[`style`])),[[B]]):i((C(),T(Ee,{key:1,clickable:``,dense:``,active:e.node.path===e.selectedPath,"active-class":`file-tree-node--selected`,style:g({paddingLeft:`${o+20}px`}),onClick:n[1]||=t=>a(`file-select`,e.node.path)},{default:m(()=>[E(Z,{avatar:``,class:`file-tree-node__icon-section`},{default:m(()=>[E(W,{name:`insert_drive_file`,size:`xs`,color:`grey-6`})]),_:1}),E(Z,{class:`text-mono`},{default:m(()=>[v(`div`,_t,[O(N(e.node.name)+` `,1),E(X,{anchor:`top middle`,self:`bottom middle`},{default:m(()=>[O(N(e.node.path),1)]),_:1})])]),_:1}),e.node.isChanged?(C(),T(Z,{key:0,side:``},{default:m(()=>[E(W,{name:`fiber_manual_record`,size:`8px`,color:`warning`})]),_:1})):j(``,!0)]),_:1},8,[`active`,`style`])),[[B]]),e.node.type===`directory`&&e.expandedFolders.has(e.node.path)&&e.node.children?(C(),y(`div`,vt,[(C(!0),y(k,null,s(e.node.children,t=>(C(),T(c,{key:t.path,node:t,"selected-path":e.selectedPath,"expanded-folders":e.expandedFolders,level:e.level+1,onToggleFolder:n[2]||=e=>a(`toggle-folder`,e),onFileSelect:n[3]||=e=>a(`file-select`,e)},null,8,[`node`,`selected-path`,`expanded-folders`,`level`]))),128))])):j(``,!0)])}}}),[[`__scopeId`,`data-v-43168dd7`]]);function bt(){let e=ae(),{t}=q(),n=Be();async function r(r,i,a){try{await xe(i,{paths:[r]}),await n.refresh()}catch(n){e.notify({type:`negative`,message:t(a),caption:n instanceof Error?n.message:String(n)})}}function i(e){return r(e,`/api/git/stage`,`changes.actions.stageError`)}function a(e){return r(e,`/api/git/unstage`,`changes.actions.unstageError`)}function o(n){e.dialog({title:t(`changes.actions.discardConfirmTitle`),message:t(`changes.actions.discardConfirmMessage`,{path:n}),persistent:!0,ok:{label:t(`changes.actions.discardConfirmOk`),color:`negative`,flat:!0},cancel:{label:t(`changes.actions.discardConfirmCancel`),flat:!0}}).onOk(()=>{r(n,`/api/git/discard`,`changes.actions.discardError`)})}return{stage:i,unstage:a,discard:o}}var xt={class:`ellipsis file-list-item__path-label`},St={class:`text-caption`},Ct={class:`text-positive`},wt={class:`text-negative q-ml-xs`},Tt=G(S({__name:`FileListItem`,props:{file:{},selected:{type:Boolean},source:{}},emits:[`click`],setup(e){let{t}=q(),{stage:n,unstage:r,discard:a}=bt(),o={added:`A`,modified:`M`,deleted:`D`,renamed:`R`},s={added:`positive`,modified:`warning`,deleted:`negative`,renamed:`purple`};return(c,l)=>i((C(),T(Ee,{clickable:``,dense:``,active:e.selected,"active-class":`file-list-item--selected`,onClick:l[3]||=e=>c.$emit(`click`)},{default:m(()=>[E(Z,{avatar:``,class:`file-list-item__icon-section`},{default:m(()=>[v(`span`,{class:x([`text-caption text-weight-bold text-mono`,`text-${s[e.file.status]}`])},N(o[e.file.status]),3)]),_:1}),E(Z,{class:`text-mono`},{default:m(()=>[v(`div`,xt,[O(N(D(Q)(e.file))+` `,1),E(X,{anchor:`top middle`,self:`bottom middle`},{default:m(()=>[O(N(D(Q)(e.file)),1)]),_:1})])]),_:1}),E(Z,{side:``,class:`file-list-item__stats`},{default:m(()=>[v(`span`,St,[v(`span`,Ct,`+`+N(e.file.additions),1),v(`span`,wt,`-`+N(e.file.deletions),1)])]),_:1}),E(Z,{side:``,class:`file-list-item__actions`},{default:m(()=>[e.source===`unstaged`?(C(),y(k,{key:0},[i((C(),T(z,{flat:``,dense:``,round:``,size:`sm`,icon:`undo`,"aria-label":D(t)(`changes.actions.discard`),onClick:l[0]||=_e(t=>D(a)(D(Q)(e.file)),[`stop`])},{default:m(()=>[E(X,null,{default:m(()=>[O(N(D(t)(`changes.actions.discard`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[B]]),i((C(),T(z,{flat:``,dense:``,round:``,size:`sm`,icon:`add`,"aria-label":D(t)(`changes.actions.stage`),onClick:l[1]||=_e(t=>D(n)(D(Q)(e.file)),[`stop`])},{default:m(()=>[E(X,null,{default:m(()=>[O(N(D(t)(`changes.actions.stage`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[B]])],64)):i((C(),T(z,{key:1,flat:``,dense:``,round:``,size:`sm`,icon:`remove`,"aria-label":D(t)(`changes.actions.unstage`),onClick:l[2]||=_e(t=>D(r)(D(Q)(e.file)),[`stop`])},{default:m(()=>[E(X,null,{default:m(()=>[O(N(D(t)(`changes.actions.unstage`)),1)]),_:1})]),_:1},8,[`aria-label`])),[[B]])]),_:1})]),_:1},8,[`active`])),[[B]])}}),[[`__scopeId`,`data-v-77d2a0e7`]]),Et=P({name:`QItemLabel`,props:{overline:Boolean,caption:Boolean,header:Boolean,lines:[Number,String]},setup(e,{slots:t}){let n=A(()=>Number.parseInt(e.lines,10)),r=A(()=>`q-item__label`+(e.overline?` q-item__label--overline text-overline`:``)+(e.caption?` q-item__label--caption text-caption`:``)+(e.header?` q-item__label--header`:``)+(n.value===1?` ellipsis`:``)),i=A(()=>e.lines!==void 0&&n.value>1?{overflow:`hidden`,display:`-webkit-box`,"-webkit-box-orient":`vertical`,"-webkit-line-clamp":n.value}:null);return()=>M(`div`,{style:i.value,class:r.value},ve(t.default))}}),Dt=S({__name:`BrowseModeToggle`,props:{modelValue:{type:Boolean,default:!1},modelModifiers:{}},emits:[`update:modelValue`],setup(e){let t=d(e,`modelValue`),{t:n}=q();return(e,r)=>(C(),T(Ee,null,{default:m(()=>[E(Z,null,{default:m(()=>[E(Et,null,{default:m(()=>[O(N(D(n)(`browse.toggle`)),1)]),_:1})]),_:1}),E(Z,{side:``},{default:m(()=>[E(K,{modelValue:t.value,"onUpdate:modelValue":r[0]||=e=>t.value=e,dense:``,size:`xs`},null,8,[`modelValue`])]),_:1})]),_:1}))}}),Ot={class:`file-list-panel__header q-pa-sm`},kt={key:1,class:`text-subtitle2 q-mb-sm`},At={class:`text-primary`},jt={key:0,class:`row justify-center q-pa-lg`},Mt={key:0,class:`text-caption text-grey-6 q-px-md q-py-sm`},Nt={key:0,class:`text-caption text-grey-6 q-px-md q-py-sm`},Pt=G(S({__name:`FileListPanel`,setup(e){let{t}=q(),{stagedFiles:n,unstagedFiles:r,loading:i}=J(Ne()),o=Be(),{source:c,browseMode:l,filter:u,selectedPath:d,expandedFolders:f,treeLoading:p,filteredDiffFiles:h,filteredTree:g,totalTreeFiles:_}=J(o);return(e,b)=>(C(),y(k,null,[v(`div`,Ot,[D(l)?(C(),y(`div`,kt,[O(N(D(t)(`browse.allFiles`))+` `,1),v(`span`,At,`(`+N(D(_))+`)`,1)])):(C(),T(ft,{key:0,modelValue:D(c),"onUpdate:modelValue":b[0]||=e=>a(c)?c.value=e:null,"staged-files-length":D(n).length,"unstaged-files-length":D(r).length},null,8,[`modelValue`,`staged-files-length`,`unstaged-files-length`])),E(pt,{modelValue:D(u),"onUpdate:modelValue":b[1]||=e=>a(u)?u.value=e:null,placeholder:D(l)?D(t)(`browse.searchPlaceholder`):D(t)(`changes.filterPlaceholder`)},null,8,[`modelValue`,`placeholder`])]),E(L),E($e,{class:`col file-list-panel__scroll`,"content-style":`padding: 4px 0`,"content-active-style":`padding: 4px 0`},{default:m(()=>[(D(l)?D(p):D(i))?(C(),y(`div`,jt,[E(H,{color:`primary`,size:`2em`})])):D(l)?(C(),y(k,{key:1},[D(g).length===0?(C(),y(`p`,Mt,N(D(u)?D(t)(`browse.noMatchingFiles`):D(t)(`browse.noFiles`)),1)):j(``,!0),(C(!0),y(k,null,s(D(g),e=>(C(),T(yt,{key:e.path,node:e,"selected-path":D(d),"expanded-folders":D(f),level:0,onToggleFolder:D(o).toggleFolder,onFileSelect:D(o).selectFile},null,8,[`node`,`selected-path`,`expanded-folders`,`onToggleFolder`,`onFileSelect`]))),128))],64)):(C(),y(k,{key:2},[D(h).length===0?(C(),y(`p`,Nt,N(D(u)?D(t)(`browse.noMatchingFiles`):D(t)(`changes.emptyFileList`)),1)):j(``,!0),(C(!0),y(k,null,s(D(h),e=>(C(),T(Tt,{key:D(Q)(e),file:e,selected:D(d)===D(Q)(e),source:D(c),onClick:t=>D(o).selectFile(D(Q)(e))},null,8,[`file`,`selected`,`source`,`onClick`]))),128))],64))]),_:1}),E(L),E(Dt,{modelValue:D(l),"onUpdate:modelValue":b[2]||=e=>a(l)?l.value=e:null},null,8,[`modelValue`])],64))}}),[[`__scopeId`,`data-v-704ed3e1`]]),Ft={class:`diff-status-bar row items-center q-gutter-x-md q-pa-sm text-body2`},It={class:`text-weight-medium`},Lt={class:`text-positive`},Rt={class:`text-negative`},zt={key:0,class:`text-grey-6`},Bt={key:1,class:`text-grey-6`},Vt={key:2,class:`text-grey-6`},Ht={key:3,class:`text-grey-6`},Ut=S({__name:`DiffStatusBar`,props:{files:{}},emits:[`expand-all`,`collapse-all`],setup(e,{emit:t}){let n=e,r=t,{t:i}=q(),a=A(()=>{let e=n.files.reduce((e,t)=>e+t.additions,0),t=n.files.reduce((e,t)=>e+t.deletions,0),r=n.files.filter(e=>e.status===`added`).length,i=n.files.filter(e=>e.status===`modified`).length,a=n.files.filter(e=>e.status===`deleted`).length,o=n.files.filter(e=>e.status===`renamed`).length;return{total:n.files.length,additions:e,deletions:t,added:r,modified:i,deleted:a,renamed:o}});return(e,t)=>(C(),y(`div`,Ft,[v(`span`,It,N(D(i)(`changes.filesChanged`,{count:a.value.total})),1),v(`span`,Lt,` +`+N(a.value.additions)+` `+N(D(i)(`changes.additions`)),1),v(`span`,Rt,` -`+N(a.value.deletions)+` `+N(D(i)(`changes.deletions`)),1),a.value.added?(C(),y(`span`,zt,N(a.value.added)+` `+N(D(i)(`changes.added`)),1)):j(``,!0),a.value.modified?(C(),y(`span`,Bt,N(a.value.modified)+` `+N(D(i)(`changes.modified`)),1)):j(``,!0),a.value.deleted?(C(),y(`span`,Vt,N(a.value.deleted)+` `+N(D(i)(`changes.deletedPlural`)),1)):j(``,!0),a.value.renamed?(C(),y(`span`,Ht,N(a.value.renamed)+` `+N(D(i)(`changes.renamed`)),1)):j(``,!0),E(Te),E(z,{dense:``,flat:``,"no-caps":``,size:`sm`,icon:`unfold_more`,label:D(i)(`changes.expandAll`),onClick:t[0]||=e=>r(`expand-all`)},null,8,[`label`]),E(z,{dense:``,flat:``,"no-caps":``,size:`sm`,icon:`unfold_less`,label:D(i)(`changes.collapseAll`),onClick:t[1]||=e=>r(`collapse-all`)},null,8,[`label`])]))}}),Wt={class:`diff-line__gutter`},Gt={class:`diff-line__gutter`},Kt={class:`diff-line__prefix`},qt={class:`diff-line__content`},Jt=G(S({__name:`DiffLineRow`,props:{line:{},tokens:{}},setup(e){let t=e,n=A(()=>({added:`+`,removed:`-`,context:` `})[t.line.type]),r=A(()=>t.line.type===`added`?`diff-line--added`:t.line.type===`removed`?`diff-line--removed`:``);function i(e){return e.colorLight&&e.colorDark?`light-dark(${e.colorLight}, ${e.colorDark})`:e.colorLight??e.colorDark}return(t,a)=>(C(),y(`div`,{class:x([`diff-line row no-wrap text-mono`,r.value])},[v(`span`,Wt,N(e.line.oldLineNumber??``),1),v(`span`,Gt,N(e.line.newLineNumber??``),1),v(`span`,Kt,N(n.value),1),v(`span`,qt,[e.tokens?(C(!0),y(k,{key:0},s(e.tokens,(e,t)=>(C(),y(`span`,{key:t,style:g({color:i(e)})},N(e.content),5))),128)):(C(),y(k,{key:1},[O(N(e.line.content),1)],64))])],2))}}),[[`__scopeId`,`data-v-e66c5ab4`]]),Yt={class:`diff-hunk`},Xt={class:`diff-hunk__header text-mono text-primary`},Zt=G(S({__name:`DiffHunkView`,props:{hunk:{},lineTokens:{}},setup(e){let t=e,n=A(()=>`@@ -${t.hunk.oldStart},${t.hunk.oldLines} +${t.hunk.newStart},${t.hunk.newLines} @@`);return(t,r)=>(C(),y(`div`,Yt,[v(`div`,Xt,N(n.value),1),(C(!0),y(k,null,s(e.hunk.lines,(t,n)=>(C(),T(Jt,{key:n,line:t,tokens:e.lineTokens?.[n]},null,8,[`line`,`tokens`]))),128))]))}}),[[`__scopeId`,`data-v-f47860bf`]]),Qt={class:`file-content-line row no-wrap text-mono`},$t={class:`file-content-line__gutter`},en={class:`file-content-line__content`},tn=G(S({__name:`FileContentLine`,props:{lineNumber:{},content:{},tokens:{}},setup(e){function t(e){return e.colorLight&&e.colorDark?`light-dark(${e.colorLight}, ${e.colorDark})`:e.colorLight??e.colorDark}return(n,r)=>(C(),y(`div`,Qt,[v(`span`,$t,N(e.lineNumber),1),v(`span`,en,[e.tokens?(C(!0),y(k,{key:0},s(e.tokens,(e,n)=>(C(),y(`span`,{key:n,style:g({color:t(e)})},N(e.content),5))),128)):(C(),y(k,{key:1},[O(N(e.content||` `),1)],64))])]))}}),[[`__scopeId`,`data-v-edbf04e6`]]),nn={ts:`typescript`,tsx:`tsx`,js:`javascript`,jsx:`jsx`,mjs:`javascript`,cjs:`javascript`,vue:`vue`,json:`json`,md:`markdown`,css:`css`,scss:`scss`,html:`html`,yml:`yaml`,yaml:`yaml`,sh:`bash`,py:`python`,go:`go`,rs:`rust`,java:`java`,kt:`kotlin`,kts:`kotlin`},rn={typescript:()=>F(()=>import(`./typescript-Utq2Cl8c.js`),__vite__mapDeps([0,1])),tsx:()=>F(()=>import(`./tsx-udAQXfEw.js`),[]),javascript:()=>F(()=>import(`./javascript-Yelw-5ZN.js`),__vite__mapDeps([2,3])),jsx:()=>F(()=>import(`./jsx-Bz0zcwM4.js`),[]),vue:()=>F(()=>import(`./vue-CSBlZ1UP.js`),__vite__mapDeps([4,5,3,6,7,1])),json:()=>F(()=>import(`./json-CaljABEy.js`),__vite__mapDeps([8,7])),markdown:()=>F(()=>import(`./markdown-BYOwaDjH.js`),[]),css:()=>F(()=>import(`./css-CdtkT07m.js`),__vite__mapDeps([9,5])),scss:()=>F(()=>import(`./scss-DHtrkMkT.js`),__vite__mapDeps([10,5])),html:()=>F(()=>import(`./html-DDNsd9lV.js`),__vite__mapDeps([11,6,5,3])),yaml:()=>F(()=>import(`./yaml-rwi0_p6S.js`),[]),bash:()=>F(()=>import(`./bash-CLZ0U2zV.js`),[]),python:()=>F(()=>import(`./python-gzcpVVnB.js`),[]),go:()=>F(()=>import(`./go-rLFTqkRN.js`),[]),rust:()=>F(()=>import(`./rust-Cfkwpbl8.js`),[]),java:()=>F(()=>import(`./java-BXcb2rRD.js`),[]),kotlin:()=>F(()=>import(`./kotlin-DhhofPvG.js`),[])},an={light:()=>F(()=>import(`./github-light-EUqPIrTm.js`),[]),dark:()=>F(()=>import(`./github-dark-C-LZuMrd.js`),[])};function on(e){let t=e.split(`.`);return t.length<2?`text`:nn[t.pop().toLowerCase()]??`text`}var sn=null,cn=new Set;async function ln(e){sn||=(async()=>{let[{createHighlighterCore:e},{createOnigurumaEngine:t}]=await Promise.all([F(()=>import(`./core-Ruj7F7dx.js`),__vite__mapDeps([12,13])),F(()=>import(`./engine-oniguruma-Bon2Icja.js`),[])]);return e({themes:[an.light(),an.dark()],langs:[],engine:t(()=>F(()=>import(`./wasm-BnjxR4X6.js`),[]))})})();let t=await sn;return cn.has(e)||(await t.loadLanguage(rn[e]()),cn.add(e)),t}async function un(e,t){if(e===`text`||!rn[e]||t.length===0)return null;try{return(await ln(e)).codeToTokensWithThemes(t.join(`
3
+ `),{lang:e,themes:{light:`github-light`,dark:`github-dark`}}).map(e=>e.map(e=>({content:e.content,colorLight:e.variants.light?.color,colorDark:e.variants.dark?.color})))}catch{return null}}async function dn(e){let t=e.hunks.flatMap(e=>e.lines.map(e=>e.content));return un(on(e.newPath||e.oldPath),t)}async function fn(e,t){return un(on(e),t)}var pn={class:`file-content-view`},mn=S({__name:`FileContentView`,props:{path:{},lines:{}},setup(t){let n=t,r=h(null),i=0;return e(()=>[n.path,n.lines],async([e,t])=>{let n=++i;if(r.value=null,t.length>0){let a=await fn(e,t);n===i&&(r.value=a)}},{immediate:!0}),(e,n)=>(C(),y(`div`,pn,[(C(!0),y(k,null,s(t.lines,(e,t)=>(C(),T(tn,{key:t,"line-number":t+1,content:e,tokens:r.value?.[t]},null,8,[`line-number`,`content`,`tokens`]))),128))]))}}),hn={key:0,class:`row justify-center q-pa-lg`},gn={key:1,class:`text-caption text-grey-6 q-pa-md q-mb-none`},_n=S({__name:`DiffFileFullView`,props:{path:{},source:{}},setup(t){let n=t,{t:r}=q(),{lines:i,isBinary:a,loading:o,fetchContent:s}=Re(),c=A(()=>n.source===`staged`?`INDEX`:`WORKTREE`);return e(()=>[n.path,c.value],([e,t])=>{s(e,t)},{immediate:!0}),(e,n)=>D(o)?(C(),y(`div`,hn,[E(H,{color:`primary`,size:`2em`})])):D(a)?(C(),y(`p`,gn,N(D(r)(`changes.binaryFile`)),1)):(C(),T(mn,{key:2,path:t.path,lines:D(i)},null,8,[`path`,`lines`]))}}),vn={},yn={class:`file-card-frame`};function bn(e,t){return C(),y(`div`,yn,[l(e.$slots,`header`,{},void 0,!0),l(e.$slots,`default`,{},void 0,!0)])}var xn=G(vn,[[`render`,bn],[`__scopeId`,`data-v-e02b3e52`]]);function Sn(e){let t=document.createElement(`textarea`);t.value=e,t.contentEditable=`true`,t.style.position=`fixed`;let n=()=>{};ce(n),document.body.append(t),t.focus(),t.select();let r=document.execCommand(`copy`);return t.remove(),I(n),r}function Cn(e){if(navigator.clipboard)return navigator.clipboard.writeText(e);let t=Sn(e);return t?Promise.resolve(!0):Promise.reject(t)}var wn=S({__name:`CopyButton`,props:{value:{},tooltip:{}},setup(e){let t=e,n=h(!1),r;async function a(){try{await Cn(t.value),n.value=!0,clearTimeout(r),r=setTimeout(()=>{n.value=!1},1500)}catch{}}return(t,r)=>i((C(),T(z,{flat:``,dense:``,round:``,size:`sm`,color:n.value?`positive`:void 0,icon:n.value?`check`:`content_copy`,"aria-label":e.tooltip,onClick:_e(a,[`stop`])},{default:m(()=>[E(X,null,{default:m(()=>[O(N(e.tooltip),1)]),_:1})]),_:1},8,[`color`,`icon`,`aria-label`])),[[B]])}}),Tn={class:`file-card-header row items-center no-wrap`},En={class:`file-card-header__name row items-center no-wrap`},Dn={class:`ellipsis text-mono file-card-header__path`},On=G(S({__name:`FileCardHeader`,props:{path:{}},setup(e){let{t}=q();return(n,r)=>(C(),y(`div`,Tn,[l(n.$slots,`leading`,{},void 0,!0),v(`div`,En,[v(`span`,Dn,N(e.path),1),E(wn,{value:e.path,tooltip:D(t)(`common.copyPath`)},null,8,[`value`,`tooltip`])]),E(Te),l(n.$slots,`default`,{},void 0,!0)]))}}),[[`__scopeId`,`data-v-f297ccaa`]]),kn={class:`diff-file-card__status-section`},An={class:`text-caption diff-file-card__stats`},jn={class:`text-positive`},Mn={class:`text-negative q-ml-xs`},Nn={key:0,class:`diff-file-card__body`},Pn={key:0,class:`text-caption text-grey-6 q-pa-md q-mb-none`},Fn={key:1,class:`text-caption text-grey-6 q-pa-md q-mb-none`},In=G(S({__name:`DiffFileCard`,props:{file:{},source:{},expanded:{type:Boolean}},emits:[`toggle`,`expand`],setup(t,{emit:n}){let r=t,a=n,{t:o}=q(),c={added:`positive`,modified:`warning`,deleted:`negative`,renamed:`purple`},l=A(()=>Q(r.file)),u=h(`diff`),d=A({get:()=>u.value===`full`,set:e=>{e?(u.value=`full`,r.expanded||a(`expand`)):r.expanded&&(u.value=`diff`)}}),f=h(null),p=0;e(()=>r.file,async e=>{let t=++p;u.value=`diff`,f.value=null;let n=await dn(e);t===p&&(f.value=n)},{immediate:!0});function g(e){if(!f.value)return null;let t=r.file.hunks.slice(0,e).reduce((e,t)=>e+t.lines.length,0);return f.value.slice(t,t+r.file.hunks[e].lines.length)}return(e,n)=>(C(),T(xn,{id:`diff-file-${l.value}`,class:`diff-file-card`},{header:m(()=>[i((C(),T(Ee,{clickable:``,dense:``,class:`diff-file-card__header-item`,onClick:n[2]||=e=>a(`toggle`)},{default:m(()=>[E(On,{path:l.value},{leading:m(()=>[E(W,{name:`chevron_right`,size:`xs`,class:x([`diff-file-card__chevron`,{"diff-file-card__chevron--expanded":t.expanded}])},null,8,[`class`])]),default:m(()=>[v(`div`,{class:`diff-file-card__toggle-section`,onClick:n[1]||=_e(()=>{},[`stop`])},[E(K,{modelValue:d.value,"onUpdate:modelValue":n[0]||=e=>d.value=e,"left-label":``,dense:``,size:`xs`,label:D(o)(`changes.showFullFile`)},null,8,[`modelValue`,`label`])]),v(`div`,kn,[E(De,{color:c[t.file.status],outline:``,rounded:``},{default:m(()=>[O(N(D(o)(`changes.fileStatus.${t.file.status}`)),1)]),_:1},8,[`color`])]),v(`span`,An,[v(`span`,jn,`+`+N(t.file.additions),1),v(`span`,Mn,`-`+N(t.file.deletions),1)])]),_:1},8,[`path`])]),_:1})),[[B]])]),default:m(()=>[t.expanded?(C(),y(`div`,Nn,[u.value===`full`?(C(),T(_n,{key:0,path:l.value,source:t.source},null,8,[`path`,`source`])):(C(),y(k,{key:1},[t.file.isBinary?(C(),y(`p`,Pn,N(D(o)(`changes.binaryFile`)),1)):t.file.hunks.length===0?(C(),y(`p`,Fn,N(D(o)(`changes.noTextChanges`)),1)):j(``,!0),(C(!0),y(k,null,s(t.file.hunks,(e,t)=>(C(),T(Zt,{key:t,hunk:e,"line-tokens":g(t)},null,8,[`hunk`,`line-tokens`]))),128))],64))])):j(``,!0)]),_:1},8,[`id`]))}}),[[`__scopeId`,`data-v-d4e4f4cd`]]),Ln={key:0,class:`q-pa-md text-grey-6`},Rn=S({__name:`DiffPanel`,setup(e){let{t}=q(),n=Be(),{source:r,diffFiles:i,expandedFiles:a}=J(n);return(e,o)=>D(i).length===0?(C(),y(`div`,Ln,N(D(t)(`changes.emptyDiffPanel`)),1)):(C(),y(k,{key:1},[E(Ut,{files:D(i),onExpandAll:D(n).expandAllFiles,onCollapseAll:D(n).collapseAllFiles},null,8,[`files`,`onExpandAll`,`onCollapseAll`]),E(L),E($e,{class:`col`,"content-style":`padding: 8px`,"content-active-style":`padding: 8px`},{default:m(()=>[(C(!0),y(k,null,s(D(i),e=>(C(),T(In,{key:D(Q)(e),file:e,source:D(r),expanded:D(a).has(D(Q)(e)),onToggle:t=>D(n).handleCardToggle(D(Q)(e)),onExpand:t=>D(n).expandFile(D(Q)(e))},null,8,[`file`,`source`,`expanded`,`onToggle`,`onExpand`]))),128))]),_:1})],64))}}),zn={key:0,class:`q-pa-md text-grey-6`},Bn={key:0,class:`row justify-center q-pa-lg`},Vn={key:1,class:`q-pa-md text-grey-6`},Hn=S({__name:`FileContentPanel`,setup(e){let{t}=q(),n=Be(),{selectedPath:r,browseFileLines:i,browseFileIsBinary:a,browseFileLoading:o}=J(n);return(e,n)=>D(r)?(C(),T(xn,{key:1,class:`col`},{header:m(()=>[E(On,{path:D(r)},null,8,[`path`])]),default:m(()=>[D(o)?(C(),y(`div`,Bn,[E(H,{color:`primary`,size:`2em`})])):D(a)?(C(),y(`div`,Vn,N(D(t)(`changes.binaryFile`)),1)):(C(),T($e,{key:2,class:`col`,"content-style":`padding: 8px`,"content-active-style":`padding: 8px`},{default:m(()=>[E(mn,{path:D(r),lines:D(i)},null,8,[`path`,`lines`])]),_:1}))]),_:1})):(C(),y(`div`,zn,N(D(t)(`browse.selectFile`)),1))}}),Un=S({__name:`FileExplorer`,setup(e){let t=Be(),{browseMode:n}=J(t);c(()=>void t.refresh());let r=Ve([`files:changed`],()=>void t.refreshFromServerEvent());return w(()=>r.close()),(e,t)=>(C(),T(Ke,null,{panel:m(()=>[E(Pt)]),content:m(()=>[D(n)?(C(),T(Hn,{key:0})):(C(),T(Rn,{key:1}))]),_:1}))}}),Wn=S({__name:`IndexPage`,setup(e){function t(e,t){return{height:`${t-e}px`}}return(e,n)=>(C(),T(ke,{"style-fn":t},{default:m(()=>[E(Un)]),_:1}))}});export{Wn as default};
@@ -0,0 +1 @@
1
+ .file-explorer[data-v-1ce1b104]{height:100%}[data-v-1ce1b104] .file-explorer__panel{flex-direction:column;flex-shrink:0;min-width:0;height:100%;display:flex}[data-v-1ce1b104] .file-explorer__content{flex-direction:column;flex-wrap:no-wrap;display:flex}.file-tree-node__icon-section[data-v-43168dd7]{min-width:0!important;padding-right:6px!important}.file-tree-node__label[data-v-43168dd7]{width:100%;min-width:0}.file-tree-node__chevron[data-v-43168dd7]{transition:transform .15s}.file-tree-node__chevron--expanded[data-v-43168dd7]{transform:rotate(90deg)}.file-tree-node--selected[data-v-43168dd7]{font-weight:500}.file-list-item__icon-section[data-v-77d2a0e7]{min-width:0!important;padding-right:6px!important}.file-list-item__path-label[data-v-77d2a0e7]{width:100%;min-width:0}.file-list-item--selected[data-v-77d2a0e7],[data-v-77d2a0e7] .file-list-item--selected{font-weight:500}.file-list-item__actions[data-v-77d2a0e7]{gap:2px;flex-direction:row!important;padding:0 0 0 6px!important}.file-list-item__stats[data-v-77d2a0e7]{padding-right:0!important}.file-list-panel__scroll[data-v-704ed3e1] .q-scrollarea__content{width:100%}.diff-line[data-v-e66c5ab4]{font-size:12px;line-height:20px}.diff-line--added[data-v-e66c5ab4]{background:var(--diff-added-bg)}.diff-line--removed[data-v-e66c5ab4]{background:var(--diff-removed-bg)}.diff-line__gutter[data-v-e66c5ab4]{text-align:right;-webkit-user-select:none;user-select:none;width:40px;color:var(--diff-gutter-color);flex:none;padding-right:8px}.diff-line__prefix[data-v-e66c5ab4]{text-align:center;-webkit-user-select:none;user-select:none;flex:none;width:16px;font-weight:600}.diff-line--added .diff-line__prefix[data-v-e66c5ab4]{color:var(--q-positive)}.diff-line--removed .diff-line__prefix[data-v-e66c5ab4]{color:var(--q-negative)}.diff-line__content[data-v-e66c5ab4]{white-space:pre;flex:1}.diff-hunk__header[data-v-f47860bf]{padding:2px 12px;font-size:12px}.file-content-line[data-v-edbf04e6]{font-size:12px;line-height:20px}.file-content-line__gutter[data-v-edbf04e6]{text-align:right;-webkit-user-select:none;user-select:none;width:48px;color:var(--diff-gutter-color);flex:none;padding-right:8px}.file-content-line__content[data-v-edbf04e6]{white-space:pre;flex:1}.file-card-frame[data-v-e02b3e52]{border:1px solid #80808033;border-radius:4px;flex-direction:column;min-height:0;display:flex;overflow:hidden}.file-card-header[data-v-f297ccaa]{background:var(--diff-header-bg);column-gap:8px;width:100%;min-width:0;padding:6px 12px}.file-card-header__name[data-v-f297ccaa]{flex:0 auto;column-gap:4px;min-width:0}.file-card-header__path[data-v-f297ccaa]{min-width:0}.diff-file-card[data-v-d4e4f4cd]{margin-bottom:8px}.diff-file-card__header-item[data-v-d4e4f4cd]{min-height:0;padding:0}.diff-file-card__chevron[data-v-d4e4f4cd]{transition:transform .15s}.diff-file-card__chevron--expanded[data-v-d4e4f4cd]{transform:rotate(90deg)}.diff-file-card__toggle-section[data-v-d4e4f4cd]{justify-content:flex-end;min-width:160px;display:flex}.diff-file-card__status-section[data-v-d4e4f4cd]{justify-content:flex-end;min-width:92px;display:flex}.diff-file-card__stats[data-v-d4e4f4cd]{text-align:right;min-width:76px;display:inline-block}.diff-file-card__body[data-v-d4e4f4cd]{border-top:1px solid #80808033;overflow-x:auto}
@@ -0,0 +1 @@
1
+ .repo-info[data-v-bce37a65]{line-height:1}