ocean-brain 0.4.2 → 0.6.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 (102) hide show
  1. package/dist/mcp.js +660 -31
  2. package/package.json +2 -1
  3. package/server/client/dist/assets/{Calendar-DI0PhQTq.js → Calendar-BytW4PeT.js} +1 -1
  4. package/server/client/dist/assets/Callout-9sJgGNRb.js +1 -0
  5. package/server/client/dist/assets/Graph-o5u-NzrA.js +1 -0
  6. package/server/client/dist/assets/{Image-DlJ4MDo3.js → Image-DxWhlIDG.js} +1 -1
  7. package/server/client/dist/assets/{Image.es-COwqkQuh.js → Image.es-B0LL3pb7.js} +1 -1
  8. package/server/client/dist/assets/Note-CYoYzZNu.js +21 -0
  9. package/server/client/dist/assets/{Plus.es-KeV96R_e.js → Plus.es-DpxzgRtY.js} +1 -1
  10. package/server/client/dist/assets/Reminders-DAepTZg1.js +1 -0
  11. package/server/client/dist/assets/Search-6KH7An44.js +1 -0
  12. package/server/client/dist/assets/{SurfaceCard-CHjcCuqZ.js → SurfaceCard-EMs50xSF.js} +1 -1
  13. package/server/client/dist/assets/Tag-C89j8x56.js +1 -0
  14. package/server/client/dist/assets/TagNotes-BTbu-f6v.js +1 -0
  15. package/server/client/dist/assets/{Trash.es-BqRTZPrI.js → Trash.es-C5x35NKF.js} +1 -1
  16. package/server/client/dist/assets/ViewNotes-DPEuki3y.js +1 -0
  17. package/server/client/dist/assets/Views-BGkuNhVd.js +1 -0
  18. package/server/client/dist/assets/{image.api-CMdQbCyN.js → image.api-DRhRQ0Gf.js} +1 -1
  19. package/server/client/dist/assets/{index-D2gRB1ig.css → index-Cd81UxEh.css} +1 -1
  20. package/server/client/dist/assets/index-DYlYUrjH.js +327 -0
  21. package/server/client/dist/assets/index-DswSFFMb.js +1 -0
  22. package/server/client/dist/assets/manage-image-C6sHhWnI.js +1 -0
  23. package/server/client/dist/assets/manage-image-detail-CJkfybR9.js +1 -0
  24. package/server/client/dist/assets/{mcp-DqGLZv90.js → mcp-piouFDNm.js} +1 -1
  25. package/server/client/dist/assets/note-core-Z6kqulGB.js +180 -0
  26. package/server/client/dist/assets/note-vendor-i1M2FSI2.js +54 -0
  27. package/server/client/dist/assets/{placeholder-BXLtvdtN.js → placeholder-DGz3CHej.js} +4 -4
  28. package/server/client/dist/assets/properties-CM4khczg.js +1 -0
  29. package/server/client/dist/assets/trash-C2lItz-b.js +1 -0
  30. package/server/client/dist/assets/{useReminderMutate-v1EXqM90.js → useReminderMutate-DHjDDHKg.js} +1 -1
  31. package/server/client/dist/assets/view-dashboard-C17WsdL7.js +99 -0
  32. package/server/client/dist/index.html +4 -4
  33. package/server/dist/features/note/graphql/note.field.resolver.js +16 -1
  34. package/server/dist/features/note/graphql/note.field.resolver.js.map +1 -1
  35. package/server/dist/features/note/graphql/note.mutation.resolver.js +192 -36
  36. package/server/dist/features/note/graphql/note.mutation.resolver.js.map +1 -1
  37. package/server/dist/features/note/graphql/note.query.resolver.js +88 -76
  38. package/server/dist/features/note/graphql/note.query.resolver.js.map +1 -1
  39. package/server/dist/features/note/graphql/note.resolver.js +3 -2
  40. package/server/dist/features/note/graphql/note.resolver.js.map +1 -1
  41. package/server/dist/features/note/graphql/note.type-defs.js +104 -1
  42. package/server/dist/features/note/graphql/note.type-defs.js.map +1 -1
  43. package/server/dist/features/note/http/mcp.js +394 -1
  44. package/server/dist/features/note/http/mcp.js.map +1 -1
  45. package/server/dist/features/note/services/cleanup.js +4 -3
  46. package/server/dist/features/note/services/cleanup.js.map +1 -1
  47. package/server/dist/features/note/services/content-blocks.js +113 -0
  48. package/server/dist/features/note/services/content-blocks.js.map +1 -0
  49. package/server/dist/features/note/services/markdown-intent-write.js +478 -0
  50. package/server/dist/features/note/services/markdown-intent-write.js.map +1 -0
  51. package/server/dist/features/note/services/markdown-patch.js +601 -0
  52. package/server/dist/features/note/services/markdown-patch.js.map +1 -0
  53. package/server/dist/features/note/services/properties.js +874 -0
  54. package/server/dist/features/note/services/properties.js.map +1 -0
  55. package/server/dist/features/note/services/search.js +10 -29
  56. package/server/dist/features/note/services/search.js.map +1 -1
  57. package/server/dist/features/note/services/snapshot.js +260 -18
  58. package/server/dist/features/note/services/snapshot.js.map +1 -1
  59. package/server/dist/features/note/services/trash.js +70 -2
  60. package/server/dist/features/note/services/trash.js.map +1 -1
  61. package/server/dist/features/note/services/write-conflict.js +87 -0
  62. package/server/dist/features/note/services/write-conflict.js.map +1 -0
  63. package/server/dist/features/note/services/write.js +121 -0
  64. package/server/dist/features/note/services/write.js.map +1 -0
  65. package/server/dist/features/view/graphql/view.query.resolver.js +31 -1
  66. package/server/dist/features/view/graphql/view.query.resolver.js.map +1 -1
  67. package/server/dist/features/view/graphql/view.type-defs.js +57 -1
  68. package/server/dist/features/view/graphql/view.type-defs.js.map +1 -1
  69. package/server/dist/features/view/services/workspace.js +367 -43
  70. package/server/dist/features/view/services/workspace.js.map +1 -1
  71. package/server/dist/modules/blocknote-tree.js +41 -0
  72. package/server/dist/modules/blocknote-tree.js.map +1 -0
  73. package/server/dist/modules/blocknote.js +47 -2
  74. package/server/dist/modules/blocknote.js.map +1 -1
  75. package/server/dist/modules/error-handler.js +7 -4
  76. package/server/dist/modules/error-handler.js.map +1 -1
  77. package/server/dist/modules/recovery-retention.js +2 -2
  78. package/server/dist/modules/recovery-retention.js.map +1 -1
  79. package/server/dist/routes/mcp.js +21 -1
  80. package/server/dist/routes/mcp.js.map +1 -1
  81. package/server/prisma/migrations/20260527073000_0017_note_properties/migration.sql +105 -0
  82. package/server/prisma/migrations/20260531073000_0018_view_query/migration.sql +3 -0
  83. package/server/prisma/schema.prisma +226 -130
  84. package/server/client/dist/assets/Callout-BAqbXI0L.js +0 -1
  85. package/server/client/dist/assets/Graph-Dhuog4tc.js +0 -1
  86. package/server/client/dist/assets/Note-ChUWU3Su.js +0 -21
  87. package/server/client/dist/assets/Reminders-D7MCTNxb.js +0 -1
  88. package/server/client/dist/assets/Search-B-fwTr5y.js +0 -1
  89. package/server/client/dist/assets/Tag-BbV2z-Db.js +0 -1
  90. package/server/client/dist/assets/TagNotes-2HKF09Jm.js +0 -1
  91. package/server/client/dist/assets/ViewNotes-TfM3Uzbp.js +0 -1
  92. package/server/client/dist/assets/Views-CUwtnfa8.js +0 -1
  93. package/server/client/dist/assets/index-B4l2UvuC.js +0 -232
  94. package/server/client/dist/assets/index-zhxZjg7V.js +0 -1
  95. package/server/client/dist/assets/manage-image-DdXb5Bkj.js +0 -1
  96. package/server/client/dist/assets/manage-image-detail-CrrXCQIX.js +0 -1
  97. package/server/client/dist/assets/note-core-GgFcksAF.js +0 -178
  98. package/server/client/dist/assets/note-vendor-B0t5F04o.js +0 -54
  99. package/server/client/dist/assets/trash-3eUAjFRh.js +0 -1
  100. package/server/client/dist/assets/view-dashboard-T6gmohr-.js +0 -90
  101. package/server/dist/features/note/graphql/note.graphql.shared.js +0 -23
  102. package/server/dist/features/note/graphql/note.graphql.shared.js.map +0 -1
@@ -1 +0,0 @@
1
- import{j as e}from"./note-vendor-B0t5F04o.js";import{$ as F,j as M,ar as Q,w as L,v as _,a5 as I,aC as K,q as i,af as E,aD as B,N as O,aE as W,P as N,F as $,T as d,as as G,B as j,a0 as H,aF as Y,i as l,W as z,d as U,ah as V,u as Z,aG as J,M as y}from"./index-B4l2UvuC.js";import{a as k}from"./graph-vendor-CUxe67Lr.js";import{S as C}from"./SurfaceCard-CHjcCuqZ.js";import"./note-core-GgFcksAF.js";const m=25,v=M(Q),S=30,R=`Deleted notes stay here for ${S} days before permanent removal`,g={title:"Permanently delete note?",description:"This note is referenced by the notes below. If you permanently delete it, those links will stay broken. Other notes will not be edited automatically.",confirmLabel:"Delete now",confirmVariant:"danger"},P=a=>U(a).format("YYYY-MM-DD HH:mm"),X=({note:a,onClose:o})=>{const s=a?.id??"",c=a?.title||"Untitled note",r=Z({queryKey:i.notes.trashDetail(s),enabled:!!a,queryFn:async()=>{const h=await J(s);if(h.type==="error")throw h;if(!h.trashedNote)throw new Error("Trashed note not found");return h.trashedNote}}),f=r.data?.contentAsMarkdown.trim()??"";return e.jsxs(y,{isOpen:!!a,onClose:o,variant:"inspect",children:[e.jsx(y.Header,{title:c,onClose:o}),e.jsx(y.Body,{children:e.jsxs("div",{className:"flex flex-col gap-3",children:[a&&e.jsxs(d,{as:"p",variant:"meta",tone:"secondary",children:["Deleted ",P(a.deletedAt)]}),r.isLoading&&e.jsx(d,{as:"p",variant:"meta",tone:"secondary",children:"Loading deleted note content..."}),r.isError&&e.jsx(d,{as:"p",variant:"meta",tone:"error",children:"Failed to load deleted note content."}),!r.isLoading&&!r.isError&&f&&e.jsx("pre",{className:"max-h-[60vh] overflow-auto whitespace-pre-wrap break-words rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-4 py-3 text-sm leading-6 text-fg-secondary",children:f}),!r.isLoading&&!r.isError&&!f&&e.jsx(d,{as:"p",variant:"meta",tone:"secondary",className:"rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-4 py-3",children:"No readable content was found for this deleted note."})]})}),e.jsx(y.Footer,{children:e.jsx(j,{variant:"ghost",size:"sm",onClick:o,children:"Close"})})]})},ee=()=>e.jsx(N,{title:"Trash",variant:"default",heading:e.jsx(l,{width:118,height:24,className:"rounded-full"}),description:e.jsx(l,{width:352,height:16,className:"rounded-full"}),children:e.jsx("div",{className:"grid gap-3",children:Array.from({length:3},(a,o)=>e.jsx(C,{padding:"compact",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0 flex-1 space-y-2",children:[e.jsx(l,{width:"40%",height:18,className:"rounded-full"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{width:168,height:14,className:"rounded-full"}),e.jsx(l,{width:176,height:14,className:"rounded-full"})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{width:56,height:24,className:"rounded-full"}),e.jsx(l,{width:72,height:24,className:"rounded-full"})]})]}),e.jsx(l,{width:92,height:32,className:"rounded-[12px]"})]})},o))})}),te=()=>{const{page:a}=v.useSearch(),o=v.useNavigate(),s=L(),c=z(),r=_(),[f,h]=k.useState(null),[x,b]=k.useState(null),{data:u}=I({queryKey:i.notes.trash({limit:m,offset:(a-1)*m}),queryFn:async()=>{const t=await K({limit:m,offset:(a-1)*m});if(t.type==="error")throw t;return t.trashedNotes}}),w=E({mutationFn:B,onSuccess:async t=>{if(t.type==="error")throw t;await Promise.all([s.invalidateQueries({queryKey:i.notes.all(),exact:!1}),s.invalidateQueries({queryKey:i.tags.all(),exact:!1}),s.invalidateQueries({queryKey:i.reminders.all(),exact:!1}),s.invalidateQueries({queryKey:i.images.all(),exact:!1}),s.invalidateQueries({queryKey:i.calendar.all(),exact:!1})]),c("The note has been restored."),o({to:O,params:{id:t.restoreTrashedNote.id}})},onError:()=>{c("Failed to restore the note.")}}),p=E({mutationFn:W,onSuccess:async t=>{if(t.type==="error")throw t;await s.invalidateQueries({queryKey:i.notes.trashAll(),exact:!1}),c("The note has been permanently deleted.")},onError:()=>{c("Failed to permanently delete the note.")}}),D=()=>{if(!x)return;const{id:t}=x;b(null),p.mutate(t)},q=async t=>{const n=await V(t);if(n.type==="error"){c("Failed to check linked notes before permanently deleting this note.");return}if(s.setQueryData(i.notes.backReferences(t),n.backReferences),n.backReferences.length>0){b({id:t,backReferences:n.backReferences});return}await r("Permanently delete this note? This cannot be undone.")&&p.mutate(t)},T=u.totalCount>0?`Trash (${u.totalCount})`:void 0,A=u.notes.find(t=>t.id===f)??null;return u.notes.length===0?e.jsx(N,{title:"Trash",variant:"default",heading:T,description:R,children:e.jsx($,{title:"Trash is empty",description:`Delete a note and you can restore it here for ${S} days before permanent removal`})}):e.jsxs(N,{title:"Trash",variant:"default",heading:T,description:R,children:[e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("div",{className:"grid gap-3",children:u.notes.map(t=>e.jsx(C,{padding:"compact",children:e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex min-w-0 items-start gap-1.5",children:[e.jsx(d,{as:"h2",variant:"body",weight:"medium",className:"min-w-0 flex-1 break-words leading-[1.25]",children:t.title||"Untitled note"}),t.pinned&&e.jsx("span",{title:"Pinned",className:"inline-flex h-5 w-5 shrink-0 items-center justify-center text-fg-tertiary",children:e.jsx(G,{className:"h-3.5 w-3.5"})})]}),e.jsx("div",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1",children:e.jsxs(d,{as:"div",variant:"meta",weight:"medium",tone:"secondary",children:["Deleted ",P(t.deletedAt)]})}),t.tagNames.length>0&&e.jsx("div",{className:"mt-2 flex flex-wrap gap-1.5",children:t.tagNames.map(n=>e.jsx(d,{as:"span",variant:"label",weight:"medium",tone:"tertiary",className:"rounded-full border border-border-subtle bg-hover-subtle px-2 py-0.5",children:n},`${t.id}-${n}`))}),t.contentPreview&&e.jsx("div",{className:"mt-3 rounded-[14px] border border-border-subtle bg-hover-subtle/50 px-3 py-2",children:e.jsx(d,{as:"p",variant:"meta",tone:"secondary",className:"line-clamp-3 whitespace-pre-wrap break-words",children:t.contentPreview})})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap gap-2 sm:justify-end",children:[e.jsx(j,{variant:"subtle",size:"sm",onClick:()=>h(t.id),children:"View content"}),e.jsx(j,{variant:"subtle",size:"sm",isLoading:w.isPending&&w.variables===t.id,onClick:()=>w.mutate(t.id),children:"Restore"}),e.jsx(j,{variant:"soft-danger",size:"sm",isLoading:p.isPending&&p.variables===t.id,onClick:()=>q(t.id),children:"Delete now"})]})]})},t.id))}),u.totalCount>m&&e.jsx(H,{page:a,last:Math.ceil(u.totalCount/m),onChange:t=>{o({search:n=>({...n,page:t})})}})]}),e.jsx(X,{note:A,onClose:()=>h(null)}),e.jsx(Y,{isOpen:!!x,title:g.title,description:g.description,references:x?.backReferences??[],confirmLabel:g.confirmLabel,confirmVariant:g.confirmVariant,onClose:()=>b(null),onConfirm:D})]})},oe=()=>{const{page:a}=v.useSearch();return e.jsx(F,{fallback:e.jsx(ee,{}),errorTitle:"Failed to load trash",errorDescription:"Retry loading deleted notes",resetKeys:[a],children:e.jsx(te,{})})};export{oe as default};
@@ -1,90 +0,0 @@
1
- import{h as n}from"./index-B4l2UvuC.js";function b(){return n(`query FetchViewWorkspace {
2
- viewWorkspace {
3
- activeTabId
4
- tabs {
5
- id
6
- title
7
- order
8
- sections {
9
- id
10
- tabId
11
- title
12
- tagNames
13
- mode
14
- limit
15
- order
16
- }
17
- }
18
- }
19
- }`)}function V(e){return n(`query FetchViewSection($id: ID!) {
20
- viewSection(id: $id) {
21
- id
22
- tabId
23
- title
24
- tagNames
25
- mode
26
- limit
27
- order
28
- }
29
- }`,{id:e})}function I(e,{limit:t=25,offset:i=0}={}){return n(`query FetchViewSectionNotes($id: ID!, $pagination: PaginationInput) {
30
- viewSectionNotes(id: $id, pagination: $pagination) {
31
- totalCount
32
- notes {
33
- id
34
- title
35
- pinned
36
- tags {
37
- id
38
- name
39
- }
40
- createdAt
41
- updatedAt
42
- }
43
- }
44
- }`,{id:e,pagination:{limit:t,offset:i}})}function w(e){return n(`mutation CreateViewTab($title: String!) {
45
- createViewTab(title: $title) {
46
- id
47
- }
48
- }`,{title:e})}function m(e,t){return n(`mutation UpdateViewTab($id: ID!, $title: String!) {
49
- updateViewTab(id: $id, title: $title) {
50
- id
51
- }
52
- }`,{id:e,title:t})}function $(e){return n(`mutation DeleteViewTab($id: ID!) {
53
- deleteViewTab(id: $id)
54
- }`,{id:e})}function f(e){return n(`mutation SetActiveViewTab($id: ID!) {
55
- setActiveViewTab(id: $id) {
56
- activeTabId
57
- tabs {
58
- id
59
- title
60
- order
61
- sections {
62
- id
63
- tabId
64
- title
65
- tagNames
66
- mode
67
- limit
68
- order
69
- }
70
- }
71
- }
72
- }`,{id:e})}function T(e){return n(`mutation ReorderViewTabs($tabIds: [ID!]!) {
73
- reorderViewTabs(tabIds: $tabIds) {
74
- id
75
- }
76
- }`,{tabIds:e})}function p(e,t){return n(`mutation CreateViewSection($tabId: ID!, $input: ViewSectionInput!) {
77
- createViewSection(tabId: $tabId, input: $input) {
78
- id
79
- }
80
- }`,{tabId:e,input:t})}function S(e,t){return n(`mutation UpdateViewSection($id: ID!, $input: ViewSectionInput!) {
81
- updateViewSection(id: $id, input: $input) {
82
- id
83
- }
84
- }`,{id:e,input:t})}function g(e){return n(`mutation DeleteViewSection($id: ID!) {
85
- deleteViewSection(id: $id)
86
- }`,{id:e})}function h(e,t){return n(`mutation ReorderViewSections($tabId: ID!, $sectionIds: [ID!]!) {
87
- reorderViewSections(tabId: $tabId, sectionIds: $sectionIds) {
88
- id
89
- }
90
- }`,{tabId:e,sectionIds:t})}const D={activeTabId:null,tabs:[]},u=e=>{const t=e.trim();return t?t.startsWith("@")?t:t.startsWith("#")?`@${t.slice(1)}`:`@${t}`:""},s=(e,t,i)=>{if(t===i)return e;const r=e.findIndex(d=>d.id===t),a=e.findIndex(d=>d.id===i);if(r<0||a<0)return e;const o=[...e],[c]=o.splice(r,1);return o.splice(a,0,c),o},v=e=>{const t=e.flatMap(i=>typeof i=="string"?i.split(","):[]);return Array.from(new Set(t.map(u).filter(Boolean)))},A=e=>e.tabs.length===0?null:e.activeTabId?e.tabs.find(t=>t.id===e.activeTabId)??e.tabs[0]??null:e.tabs[0]??null,N=(e,t)=>e.tabs.some(i=>i.id===t)?{...e,activeTabId:t}:e,W=(e,t,i)=>({...e,tabs:s(e.tabs,t,i)}),y=(e,t,i,r)=>({...e,tabs:e.tabs.map(a=>a.id===t?{...a,sections:s(a.sections,i,r)}:a)}),x=e=>e==="or"?"Matches any selected tag":"Matches all selected tags",M=e=>e==="or"?"OR":"AND",q=e=>({page:1,sectionId:e.id});export{D as E,x as a,q as b,b as c,A as d,f as e,I as f,M as g,T as h,y as i,h as j,w as k,$ as l,p as m,v as n,S as o,g as p,V as q,W as r,N as s,m as u};
@@ -1,23 +0,0 @@
1
- const extractBlocksByType = (type, dataArray) => {
2
- let result = [];
3
- for (const data of dataArray) {
4
- if (data.type === type) {
5
- result.push(data);
6
- }
7
- if (data.children && data.children.length > 0) {
8
- result = result.concat(extractBlocksByType(type, data.children));
9
- }
10
- if (data.content && data.content.length > 0) {
11
- for (const contentItem of data.content) {
12
- if (contentItem.type === type) {
13
- result.push(contentItem);
14
- }
15
- }
16
- }
17
- }
18
- return result;
19
- };
20
- export {
21
- extractBlocksByType
22
- };
23
- //# sourceMappingURL=note.graphql.shared.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/features/note/graphql/note.graphql.shared.ts"],"sourcesContent":["interface BlockNote<T = unknown> {\n id: string;\n type: string;\n props: T;\n content?: BlockNote<T>[];\n children?: BlockNote<T>[];\n}\n\nexport const extractBlocksByType = <T>(type: string, dataArray: BlockNote[]): BlockNote<T>[] => {\n let result: BlockNote[] = [];\n\n for (const data of dataArray) {\n if (data.type === type) {\n result.push(data);\n }\n\n if (data.children && data.children.length > 0) {\n result = result.concat(extractBlocksByType(type, data.children));\n }\n\n if (data.content && data.content.length > 0) {\n for (const contentItem of data.content) {\n if (contentItem.type === type) {\n result.push(contentItem);\n }\n }\n }\n }\n\n return result as BlockNote<T>[];\n};\n"],"mappings":"AAQO,MAAM,sBAAsB,CAAI,MAAc,cAA2C;AAC5F,MAAI,SAAsB,CAAC;AAE3B,aAAW,QAAQ,WAAW;AAC1B,QAAI,KAAK,SAAS,MAAM;AACpB,aAAO,KAAK,IAAI;AAAA,IACpB;AAEA,QAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC3C,eAAS,OAAO,OAAO,oBAAoB,MAAM,KAAK,QAAQ,CAAC;AAAA,IACnE;AAEA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AACzC,iBAAW,eAAe,KAAK,SAAS;AACpC,YAAI,YAAY,SAAS,MAAM;AAC3B,iBAAO,KAAK,WAAW;AAAA,QAC3B;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AACX;","names":[]}