@agimon-ai/po-file-edit 0.0.0-alpha.34 → 0.0.0-alpha.35
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.
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createApiClient, defineChannelFile, defineFileLinks, defineNativePlugin, defineSessionStore, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
|
|
1
|
+
import { createApiClient, defineChannelFile, defineFileLinks, defineNativePlugin, defineSessionStore, encodeBase64, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
|
|
2
2
|
import { View } from "react-native-unistyles/components/native/View";
|
|
3
3
|
import { Text } from "react-native-unistyles/components/native/Text";
|
|
4
4
|
import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
|
|
5
5
|
import { Button, CloseIcon, CodeBlock, CopyButton, DownloadIcon, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, KebabIcon, Label, Markdown, SegmentedControl, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, Textarea, fontOf } from "@agimon-ai/po-native-components";
|
|
6
|
-
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
6
|
+
import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
7
7
|
import { StyleSheet } from "react-native-unistyles";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
//#region src/types/webFiles.ts
|
|
@@ -294,6 +294,107 @@ async function prepareFileSave(sessionId, path, signal) {
|
|
|
294
294
|
};
|
|
295
295
|
}
|
|
296
296
|
//#endregion
|
|
297
|
+
//#region src/extensions/workspaces/sessions/(frontend)/_components/FileDiff.native.tsx
|
|
298
|
+
const ROW_STEP = 200;
|
|
299
|
+
/** Mount only the disclosed prefix; source line numbers and single-line comment anchors stay intact. */
|
|
300
|
+
function FileDiff({ hunks, comment, initialRows = ROW_STEP, label = "file-diff" }) {
|
|
301
|
+
const [limit, setLimit] = useState(initialRows);
|
|
302
|
+
const total = useMemo(() => hunks.reduce((count, hunk) => count + hunk.rows.length, 0), [hunks]);
|
|
303
|
+
const visible = useMemo(() => {
|
|
304
|
+
const result = [];
|
|
305
|
+
let remaining = limit;
|
|
306
|
+
for (const hunk of hunks) {
|
|
307
|
+
if (remaining <= 0) break;
|
|
308
|
+
result.push({
|
|
309
|
+
...hunk,
|
|
310
|
+
rows: hunk.rows.slice(0, remaining)
|
|
311
|
+
});
|
|
312
|
+
remaining -= hunk.rows.length;
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}, [hunks, limit]);
|
|
316
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
317
|
+
style: styles$3.diff,
|
|
318
|
+
testID: label,
|
|
319
|
+
children: [visible.map((hunk, index) => {
|
|
320
|
+
return hunk.rows.length ? /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
321
|
+
style: styles$3.meta,
|
|
322
|
+
children: ["line ", hunk.start]
|
|
323
|
+
}), hunk.rows.map((row, position) => /* @__PURE__ */ jsx(Button, {
|
|
324
|
+
variant: "ghost",
|
|
325
|
+
accessibilityLabel: `comment on ${row.marker === "-" ? "removed" : "new"} line ${row.line}`,
|
|
326
|
+
onPress: () => comment({
|
|
327
|
+
snippet: row.content,
|
|
328
|
+
side: row.marker === "-" ? "old" : "new",
|
|
329
|
+
startLine: row.line,
|
|
330
|
+
endLine: row.line
|
|
331
|
+
}),
|
|
332
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
333
|
+
selectable: true,
|
|
334
|
+
style: row.marker === "+" ? styles$3.added : row.marker === "-" ? styles$3.removed : styles$3.code,
|
|
335
|
+
children: [
|
|
336
|
+
row.marker,
|
|
337
|
+
" ",
|
|
338
|
+
row.line,
|
|
339
|
+
" ",
|
|
340
|
+
row.content
|
|
341
|
+
]
|
|
342
|
+
})
|
|
343
|
+
}, `${row.line}-${position}`))] }, `${hunk.start}-${index}`) : null;
|
|
344
|
+
}), total ? /* @__PURE__ */ jsxs(View, {
|
|
345
|
+
style: styles$3.diff,
|
|
346
|
+
children: [/* @__PURE__ */ jsxs(Text, {
|
|
347
|
+
accessibilityLiveRegion: "polite",
|
|
348
|
+
style: styles$3.meta,
|
|
349
|
+
children: [
|
|
350
|
+
"Showing ",
|
|
351
|
+
Math.min(limit, total).toLocaleString("en-US"),
|
|
352
|
+
" of ",
|
|
353
|
+
total.toLocaleString("en-US"),
|
|
354
|
+
" rows"
|
|
355
|
+
]
|
|
356
|
+
}), limit < total ? /* @__PURE__ */ jsxs(Button, {
|
|
357
|
+
variant: "outline",
|
|
358
|
+
onPress: () => setLimit((value) => Math.min(total, value + ROW_STEP)),
|
|
359
|
+
children: [
|
|
360
|
+
"Show ",
|
|
361
|
+
Math.min(ROW_STEP, total - limit),
|
|
362
|
+
" more rows"
|
|
363
|
+
]
|
|
364
|
+
}) : null]
|
|
365
|
+
}) : null]
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
const styles$3 = StyleSheet.create((theme) => ({
|
|
369
|
+
diff: {
|
|
370
|
+
gap: theme.spacing(2),
|
|
371
|
+
uni__dependencies: [0]
|
|
372
|
+
},
|
|
373
|
+
code: {
|
|
374
|
+
fontFamily: fontOf(theme.fontFamily.mono),
|
|
375
|
+
fontSize: theme.fontSize.sm,
|
|
376
|
+
color: theme.colors.text,
|
|
377
|
+
uni__dependencies: [0]
|
|
378
|
+
},
|
|
379
|
+
added: {
|
|
380
|
+
fontFamily: fontOf(theme.fontFamily.mono),
|
|
381
|
+
fontSize: theme.fontSize.sm,
|
|
382
|
+
color: theme.colors.green,
|
|
383
|
+
uni__dependencies: [0]
|
|
384
|
+
},
|
|
385
|
+
removed: {
|
|
386
|
+
fontFamily: fontOf(theme.fontFamily.mono),
|
|
387
|
+
fontSize: theme.fontSize.sm,
|
|
388
|
+
color: theme.colors.red,
|
|
389
|
+
uni__dependencies: [0]
|
|
390
|
+
},
|
|
391
|
+
meta: {
|
|
392
|
+
fontSize: theme.fontSize.sm,
|
|
393
|
+
color: theme.colors.dim,
|
|
394
|
+
uni__dependencies: [0]
|
|
395
|
+
}
|
|
396
|
+
}));
|
|
397
|
+
//#endregion
|
|
297
398
|
//#region src/extensions/workspaces/sessions/(frontend)/_components/FilePreview.native.tsx
|
|
298
399
|
const MEDIA = /\.(?:png|jpe?g|gif|webp|bmp|svg|ico|mp3|wav|m4a|ogg|mp4|mov|webm|pdf)$/iu;
|
|
299
400
|
const MAX_MEDIA_BYTES = 5242880;
|
|
@@ -301,23 +402,6 @@ const URL_OR_ANCHOR = /^(?:[a-z][a-z\d+.-]*:|\/\/|#|\?)/iu;
|
|
|
301
402
|
function isMediaPath(path) {
|
|
302
403
|
return MEDIA.test(path);
|
|
303
404
|
}
|
|
304
|
-
function base64(bytes) {
|
|
305
|
-
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
306
|
-
const parts = [];
|
|
307
|
-
let chunk = "";
|
|
308
|
-
for (let offset = 0; offset < bytes.length; offset += 3) {
|
|
309
|
-
const first = bytes[offset];
|
|
310
|
-
const second = bytes[offset + 1];
|
|
311
|
-
const third = bytes[offset + 2];
|
|
312
|
-
chunk += alphabet[first >> 2] + alphabet[(first & 3) << 4 | (second ?? 0) >> 4] + (second === void 0 ? "=" : alphabet[(second & 15) << 2 | (third ?? 0) >> 6]) + (third === void 0 ? "=" : alphabet[third & 63]);
|
|
313
|
-
if (chunk.length >= 8192) {
|
|
314
|
-
parts.push(chunk);
|
|
315
|
-
chunk = "";
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
parts.push(chunk);
|
|
319
|
-
return parts.join("");
|
|
320
|
-
}
|
|
321
405
|
/** One media file's bytes through the package's guarded file route, as base64 with its content type. */
|
|
322
406
|
async function fetchMedia(sessionId, path, signal) {
|
|
323
407
|
const result = await api.session(sessionId).file({
|
|
@@ -331,7 +415,7 @@ async function fetchMedia(sessionId, path, signal) {
|
|
|
331
415
|
const type = result.response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
332
416
|
if (!/^(?:image\/[a-z0-9.+-]+|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+|application\/pdf)$/u.test(type)) throw new Error("This media type cannot be previewed.");
|
|
333
417
|
return {
|
|
334
|
-
data:
|
|
418
|
+
data: encodeBase64(bytes),
|
|
335
419
|
type
|
|
336
420
|
};
|
|
337
421
|
}
|
|
@@ -382,6 +466,73 @@ function SessionMedia({ sessionId, path, renderMediaPreview }) {
|
|
|
382
466
|
children: "This host cannot display this media preview."
|
|
383
467
|
});
|
|
384
468
|
}
|
|
469
|
+
/** One document's requested images, invalidated only by their own file revisions. */
|
|
470
|
+
function markdownImages(sessionId, documentPath) {
|
|
471
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
472
|
+
const stamp = (imagePath) => {
|
|
473
|
+
const session = files.select(files.store.state, sessionId);
|
|
474
|
+
const item = session.items.find((entry) => entry.path === imagePath || entry.relPath === imagePath);
|
|
475
|
+
return JSON.stringify([
|
|
476
|
+
item?.count,
|
|
477
|
+
item?.at,
|
|
478
|
+
session.detail[imagePath]?.working.hash
|
|
479
|
+
]);
|
|
480
|
+
};
|
|
481
|
+
const load = async (source) => {
|
|
482
|
+
if (sessionId === null || URL_OR_ANCHOR.test(source)) throw new Error("This image cannot be loaded.");
|
|
483
|
+
const imagePath = documentRelative(documentPath, source);
|
|
484
|
+
let image = loaded.get(imagePath);
|
|
485
|
+
if (!image) {
|
|
486
|
+
image = { stamp: stamp(imagePath) };
|
|
487
|
+
loaded.set(imagePath, image);
|
|
488
|
+
}
|
|
489
|
+
const cached = image;
|
|
490
|
+
cached.asset ??= fetchMedia(sessionId, imagePath, new AbortController().signal).then((media) => {
|
|
491
|
+
if (!media.type.startsWith("image/")) throw new Error("This file is not an image.");
|
|
492
|
+
return {
|
|
493
|
+
url: `data:${media.type};base64,${media.data}`,
|
|
494
|
+
dispose: () => {}
|
|
495
|
+
};
|
|
496
|
+
}).catch((error) => {
|
|
497
|
+
cached.asset = void 0;
|
|
498
|
+
throw error;
|
|
499
|
+
});
|
|
500
|
+
return cached.asset;
|
|
501
|
+
};
|
|
502
|
+
let snapshot = load;
|
|
503
|
+
const subscribe = (listener) => {
|
|
504
|
+
const subscription = files.store.subscribe(() => {
|
|
505
|
+
let changed = false;
|
|
506
|
+
for (const [imagePath, image] of loaded) {
|
|
507
|
+
const next = stamp(imagePath);
|
|
508
|
+
if (next === image.stamp) continue;
|
|
509
|
+
loaded.set(imagePath, { stamp: next });
|
|
510
|
+
changed = true;
|
|
511
|
+
}
|
|
512
|
+
if (changed) {
|
|
513
|
+
snapshot = (source) => load(source);
|
|
514
|
+
listener();
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
return () => subscription.unsubscribe();
|
|
518
|
+
};
|
|
519
|
+
return {
|
|
520
|
+
subscribe,
|
|
521
|
+
snapshot: () => snapshot
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
function MarkdownPreview({ path, working, sessionId, fileTabFor, openTransientTab }) {
|
|
525
|
+
const images = useMemo(() => markdownImages(sessionId, path), [sessionId, path]);
|
|
526
|
+
const loadImage = useSyncExternalStore(images.subscribe, images.snapshot);
|
|
527
|
+
return /* @__PURE__ */ jsx(Markdown, {
|
|
528
|
+
text: working.content,
|
|
529
|
+
onFileLink: (file) => {
|
|
530
|
+
const tab = fileTabFor(file);
|
|
531
|
+
return tab ? () => openTransientTab(tab) : void 0;
|
|
532
|
+
},
|
|
533
|
+
loadImage
|
|
534
|
+
});
|
|
535
|
+
}
|
|
385
536
|
/** Rendering is separate from reading: only the guarded package API supplies file content or bytes. */
|
|
386
537
|
function FilePreview({ path, working, ...props }) {
|
|
387
538
|
if (MEDIA.test(path)) return /* @__PURE__ */ jsx(SessionMedia, {
|
|
@@ -404,25 +555,11 @@ function FilePreview({ path, working, ...props }) {
|
|
|
404
555
|
style: styles$2.error,
|
|
405
556
|
children: "This host cannot display HTML previews."
|
|
406
557
|
});
|
|
407
|
-
if (/\.(?:md|markdown)$/iu.test(path)) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
const tab = props.fileTabFor(file);
|
|
413
|
-
return tab ? () => props.openTransientTab(tab) : void 0;
|
|
414
|
-
},
|
|
415
|
-
loadImage: async (source) => {
|
|
416
|
-
if (sessionId === null || URL_OR_ANCHOR.test(source)) throw new Error("This image cannot be loaded.");
|
|
417
|
-
const media = await fetchMedia(sessionId, documentRelative(path, source), new AbortController().signal);
|
|
418
|
-
if (!media.type.startsWith("image/")) throw new Error("This file is not an image.");
|
|
419
|
-
return {
|
|
420
|
-
url: `data:${media.type};base64,${media.data}`,
|
|
421
|
-
dispose: () => {}
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
}
|
|
558
|
+
if (/\.(?:md|markdown)$/iu.test(path)) return /* @__PURE__ */ jsx(MarkdownPreview, {
|
|
559
|
+
...props,
|
|
560
|
+
path,
|
|
561
|
+
working
|
|
562
|
+
}, working.hash);
|
|
426
563
|
return /* @__PURE__ */ jsx(CodeBlock, {
|
|
427
564
|
text: working.content,
|
|
428
565
|
language: path.split(".").at(-1)
|
|
@@ -446,35 +583,6 @@ const styles$2 = StyleSheet.create((theme) => ({
|
|
|
446
583
|
}));
|
|
447
584
|
//#endregion
|
|
448
585
|
//#region src/extensions/workspaces/sessions/(frontend)/_components/FilePanel.native.tsx
|
|
449
|
-
function Diff({ hunks, comment }) {
|
|
450
|
-
return /* @__PURE__ */ jsx(View, {
|
|
451
|
-
style: styles$1.diff,
|
|
452
|
-
children: hunks.map((hunk, index) => /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
453
|
-
style: styles$1.meta,
|
|
454
|
-
children: ["line ", hunk.start]
|
|
455
|
-
}), hunk.rows.map((row, position) => /* @__PURE__ */ jsx(Button, {
|
|
456
|
-
variant: "ghost",
|
|
457
|
-
accessibilityLabel: `comment on ${row.marker === "-" ? "removed" : "new"} line ${row.line}`,
|
|
458
|
-
onPress: () => comment({
|
|
459
|
-
snippet: row.content,
|
|
460
|
-
side: row.marker === "-" ? "old" : "new",
|
|
461
|
-
startLine: row.line,
|
|
462
|
-
endLine: row.line
|
|
463
|
-
}),
|
|
464
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
465
|
-
selectable: true,
|
|
466
|
-
style: row.marker === "+" ? styles$1.added : row.marker === "-" ? styles$1.removed : styles$1.code,
|
|
467
|
-
children: [
|
|
468
|
-
row.marker,
|
|
469
|
-
" ",
|
|
470
|
-
row.line,
|
|
471
|
-
" ",
|
|
472
|
-
row.content
|
|
473
|
-
]
|
|
474
|
-
})
|
|
475
|
-
}, `${row.line}-${position}`))] }, `${hunk.start}-${index}`))
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
586
|
function ReviewSheet({ selection, close, submit }) {
|
|
479
587
|
const [body, setBody] = useState("");
|
|
480
588
|
const [snippet, setSnippet] = useState(selection.snippet);
|
|
@@ -514,6 +622,23 @@ function ReviewSheet({ selection, close, submit }) {
|
|
|
514
622
|
] })] })
|
|
515
623
|
});
|
|
516
624
|
}
|
|
625
|
+
/** Cache the selected file snapshot, not the session record or a freshly filtered comments array. */
|
|
626
|
+
function fileSnapshot(sessionId, filePath) {
|
|
627
|
+
let previous;
|
|
628
|
+
return () => {
|
|
629
|
+
const session = files.select(files.store.state, sessionId);
|
|
630
|
+
const next = {
|
|
631
|
+
detail: session.detail[filePath],
|
|
632
|
+
loading: session.loading.includes(filePath),
|
|
633
|
+
error: session.errors[filePath],
|
|
634
|
+
revision: session.items.find((item) => item.path === filePath)?.count ?? 0,
|
|
635
|
+
comments: session.comments.filter((comment) => comment.path === filePath)
|
|
636
|
+
};
|
|
637
|
+
if (previous && previous.detail === next.detail && previous.loading === next.loading && previous.error === next.error && previous.revision === next.revision && previous.comments.length === next.comments.length && previous.comments.every((comment, index) => comment === next.comments[index])) return previous;
|
|
638
|
+
previous = next;
|
|
639
|
+
return next;
|
|
640
|
+
};
|
|
641
|
+
}
|
|
517
642
|
/** File writes retain the existing containment and stale-hash guards; deletion always asks first. */
|
|
518
643
|
function FilePanel({ filePath, relPath, ...props }) {
|
|
519
644
|
const { sessionId, sendSessionFrame, closeTransientTab } = props;
|
|
@@ -521,10 +646,9 @@ function FilePanel({ filePath, relPath, ...props }) {
|
|
|
521
646
|
const subscription = files.store.subscribe(listener);
|
|
522
647
|
return () => subscription.unsubscribe();
|
|
523
648
|
}, []);
|
|
524
|
-
const
|
|
525
|
-
const detail =
|
|
649
|
+
const snapshot = useMemo(() => fileSnapshot(sessionId, filePath), [sessionId, filePath]);
|
|
650
|
+
const { detail, loading, error, revision, comments } = useSyncExternalStore(subscribe, snapshot);
|
|
526
651
|
const working = detail?.working;
|
|
527
|
-
const comments = session.comments.filter((comment) => comment.path === filePath);
|
|
528
652
|
const [view, setView] = useState("preview");
|
|
529
653
|
const [source, setSource] = useState();
|
|
530
654
|
const [expanded, setExpanded] = useState();
|
|
@@ -536,7 +660,6 @@ function FilePanel({ filePath, relPath, ...props }) {
|
|
|
536
660
|
const [reviewError, setReviewError] = useState();
|
|
537
661
|
const outside = relPath === ".." || relPath.startsWith("../") || relPath.startsWith("/") || relPath.startsWith("..\\") || /^[a-z]:[\\/]/iu.test(relPath);
|
|
538
662
|
const writable = sessionId !== null && !outside && working !== void 0 && !working.unavailable;
|
|
539
|
-
const revision = session.items.find((item) => item.path === filePath)?.count ?? 0;
|
|
540
663
|
useEffect(() => {
|
|
541
664
|
if (sessionId === null) return;
|
|
542
665
|
let cancelled = false;
|
|
@@ -693,14 +816,14 @@ function FilePanel({ filePath, relPath, ...props }) {
|
|
|
693
816
|
style: styles$1.meta,
|
|
694
817
|
children: "editing"
|
|
695
818
|
}) : null,
|
|
696
|
-
|
|
819
|
+
loading && !detail ? /* @__PURE__ */ jsx(Text, {
|
|
697
820
|
style: styles$1.meta,
|
|
698
821
|
children: "reading this file's history…"
|
|
699
822
|
}) : null,
|
|
700
|
-
|
|
823
|
+
error ? /* @__PURE__ */ jsx(Text, {
|
|
701
824
|
accessibilityRole: "alert",
|
|
702
825
|
style: styles$1.error,
|
|
703
|
-
children:
|
|
826
|
+
children: error
|
|
704
827
|
}) : null,
|
|
705
828
|
detail ? view === "diff" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
706
829
|
/* @__PURE__ */ jsxs(Text, {
|
|
@@ -716,10 +839,10 @@ function FilePanel({ filePath, relPath, ...props }) {
|
|
|
716
839
|
style: styles$1.meta,
|
|
717
840
|
children: detail.cumulative.note
|
|
718
841
|
}) : null,
|
|
719
|
-
detail.cumulative.hunks ? /* @__PURE__ */ jsx(
|
|
842
|
+
detail.cumulative.hunks ? /* @__PURE__ */ jsx(FileDiff, {
|
|
720
843
|
hunks: detail.cumulative.hunks,
|
|
721
844
|
comment: setDraft
|
|
722
|
-
}) : null,
|
|
845
|
+
}, `${sessionId}:${filePath}`) : null,
|
|
723
846
|
/* @__PURE__ */ jsxs(Text, {
|
|
724
847
|
style: styles$1.title,
|
|
725
848
|
children: [detail.versions.length, " changes this session"]
|
|
@@ -739,10 +862,10 @@ function FilePanel({ filePath, relPath, ...props }) {
|
|
|
739
862
|
version.removals,
|
|
740
863
|
version.origin === "scan" ? " · no baseline" : ""
|
|
741
864
|
]
|
|
742
|
-
}), expanded === version.index ? version.hunks ? /* @__PURE__ */ jsx(
|
|
865
|
+
}), expanded === version.index ? version.hunks ? /* @__PURE__ */ jsx(FileDiff, {
|
|
743
866
|
hunks: version.hunks,
|
|
744
867
|
comment: setDraft
|
|
745
|
-
}) : /* @__PURE__ */ jsx(Text, {
|
|
868
|
+
}, `${sessionId}:${filePath}`) : /* @__PURE__ */ jsx(Text, {
|
|
746
869
|
style: styles$1.meta,
|
|
747
870
|
children: version.note ?? "nothing to show"
|
|
748
871
|
}) : null] }, version.index))
|
|
@@ -926,24 +1049,6 @@ const styles$1 = StyleSheet.create((theme) => ({
|
|
|
926
1049
|
color: theme.colors.hi,
|
|
927
1050
|
uni__dependencies: [0]
|
|
928
1051
|
},
|
|
929
|
-
code: {
|
|
930
|
-
fontFamily: fontOf(theme.fontFamily.mono),
|
|
931
|
-
fontSize: theme.fontSize.sm,
|
|
932
|
-
color: theme.colors.text,
|
|
933
|
-
uni__dependencies: [0]
|
|
934
|
-
},
|
|
935
|
-
added: {
|
|
936
|
-
fontFamily: fontOf(theme.fontFamily.mono),
|
|
937
|
-
fontSize: theme.fontSize.sm,
|
|
938
|
-
color: theme.colors.green,
|
|
939
|
-
uni__dependencies: [0]
|
|
940
|
-
},
|
|
941
|
-
removed: {
|
|
942
|
-
fontFamily: fontOf(theme.fontFamily.mono),
|
|
943
|
-
fontSize: theme.fontSize.sm,
|
|
944
|
-
color: theme.colors.red,
|
|
945
|
-
uni__dependencies: [0]
|
|
946
|
-
},
|
|
947
1052
|
meta: {
|
|
948
1053
|
fontSize: theme.fontSize.sm,
|
|
949
1054
|
color: theme.colors.dim,
|