@glw907/cairn-cms 0.5.1 → 0.6.0-rc.1

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 (234) hide show
  1. package/dist/auth/crypto.d.ts +13 -0
  2. package/dist/auth/crypto.d.ts.map +1 -0
  3. package/dist/auth/crypto.js +31 -0
  4. package/dist/auth/store.d.ts +41 -0
  5. package/dist/auth/store.d.ts.map +1 -0
  6. package/dist/auth/store.js +115 -0
  7. package/dist/auth/types.d.ts +25 -0
  8. package/dist/auth/types.d.ts.map +1 -0
  9. package/dist/auth/types.js +1 -0
  10. package/dist/components/AdminLayout.svelte +58 -164
  11. package/dist/components/AdminLayout.svelte.d.ts +14 -18
  12. package/dist/components/AdminLayout.svelte.d.ts.map +1 -1
  13. package/dist/components/ComponentPalette.svelte +36 -20
  14. package/dist/components/ComponentPalette.svelte.d.ts +11 -4
  15. package/dist/components/ComponentPalette.svelte.d.ts.map +1 -1
  16. package/dist/components/ConceptList.svelte +81 -0
  17. package/dist/components/ConceptList.svelte.d.ts +13 -0
  18. package/dist/components/ConceptList.svelte.d.ts.map +1 -0
  19. package/dist/components/ConfirmPage.svelte +23 -20
  20. package/dist/components/ConfirmPage.svelte.d.ts +6 -0
  21. package/dist/components/ConfirmPage.svelte.d.ts.map +1 -1
  22. package/dist/components/EditPage.svelte +155 -136
  23. package/dist/components/EditPage.svelte.d.ts +16 -8
  24. package/dist/components/EditPage.svelte.d.ts.map +1 -1
  25. package/dist/components/LoginPage.svelte +42 -52
  26. package/dist/components/LoginPage.svelte.d.ts +12 -0
  27. package/dist/components/LoginPage.svelte.d.ts.map +1 -1
  28. package/dist/components/ManageEditors.svelte +81 -0
  29. package/dist/components/ManageEditors.svelte.d.ts +23 -0
  30. package/dist/components/ManageEditors.svelte.d.ts.map +1 -0
  31. package/dist/components/MarkdownEditor.svelte +81 -0
  32. package/dist/components/MarkdownEditor.svelte.d.ts +20 -0
  33. package/dist/components/MarkdownEditor.svelte.d.ts.map +1 -0
  34. package/dist/components/NavTree.svelte +73 -63
  35. package/dist/components/NavTree.svelte.d.ts +13 -4
  36. package/dist/components/NavTree.svelte.d.ts.map +1 -1
  37. package/dist/components/cairn-admin.css +42 -0
  38. package/dist/components/index.d.ts +3 -2
  39. package/dist/components/index.d.ts.map +1 -1
  40. package/dist/components/index.js +5 -4
  41. package/dist/content/compose.d.ts +7 -0
  42. package/dist/content/compose.d.ts.map +1 -0
  43. package/dist/content/compose.js +32 -0
  44. package/dist/content/concepts.d.ts +17 -0
  45. package/dist/content/concepts.d.ts.map +1 -0
  46. package/dist/content/concepts.js +41 -0
  47. package/dist/content/frontmatter.d.ts +18 -0
  48. package/dist/content/frontmatter.d.ts.map +1 -0
  49. package/dist/content/frontmatter.js +58 -0
  50. package/dist/content/ids.d.ts +17 -0
  51. package/dist/content/ids.d.ts.map +1 -0
  52. package/dist/content/ids.js +33 -0
  53. package/dist/content/types.d.ts +210 -0
  54. package/dist/content/types.d.ts.map +1 -0
  55. package/dist/content/types.js +1 -0
  56. package/dist/content/validate.d.ts +13 -0
  57. package/dist/content/validate.d.ts.map +1 -0
  58. package/dist/content/validate.js +45 -0
  59. package/dist/email.d.ts +25 -12
  60. package/dist/email.d.ts.map +1 -1
  61. package/dist/email.js +24 -24
  62. package/dist/env.d.ts +24 -0
  63. package/dist/env.d.ts.map +1 -0
  64. package/dist/env.js +29 -0
  65. package/dist/github/credentials.d.ts +12 -0
  66. package/dist/github/credentials.d.ts.map +1 -0
  67. package/dist/github/credentials.js +11 -0
  68. package/dist/github/repo.d.ts +49 -0
  69. package/dist/github/repo.d.ts.map +1 -0
  70. package/dist/github/repo.js +123 -0
  71. package/dist/github/signing.d.ts +17 -0
  72. package/dist/github/signing.d.ts.map +1 -0
  73. package/dist/github/signing.js +79 -0
  74. package/dist/github/types.d.ts +35 -0
  75. package/dist/github/types.d.ts.map +1 -0
  76. package/dist/github/types.js +19 -0
  77. package/dist/index.d.ts +27 -8
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +21 -10
  80. package/dist/{nav.d.ts → nav/site-config.d.ts} +16 -24
  81. package/dist/nav/site-config.d.ts.map +1 -0
  82. package/dist/{nav.js → nav/site-config.js} +27 -13
  83. package/dist/render/glyph.d.ts +1 -1
  84. package/dist/render/glyph.d.ts.map +1 -1
  85. package/dist/render/index.d.ts +5 -5
  86. package/dist/render/index.d.ts.map +1 -1
  87. package/dist/render/index.js +6 -6
  88. package/dist/render/pipeline.d.ts +7 -6
  89. package/dist/render/pipeline.d.ts.map +1 -1
  90. package/dist/render/pipeline.js +5 -5
  91. package/dist/render/registry.d.ts +10 -6
  92. package/dist/render/registry.d.ts.map +1 -1
  93. package/dist/render/registry.js +8 -6
  94. package/dist/render/rehype-dispatch.d.ts +8 -7
  95. package/dist/render/rehype-dispatch.d.ts.map +1 -1
  96. package/dist/render/rehype-dispatch.js +16 -14
  97. package/dist/render/remark-directives.d.ts +1 -1
  98. package/dist/render/remark-directives.d.ts.map +1 -1
  99. package/dist/render/sanitize.d.ts +8 -0
  100. package/dist/render/sanitize.d.ts.map +1 -0
  101. package/dist/render/sanitize.js +26 -0
  102. package/dist/sveltekit/auth-routes.d.ts +23 -0
  103. package/dist/sveltekit/auth-routes.d.ts.map +1 -0
  104. package/dist/sveltekit/auth-routes.js +85 -0
  105. package/dist/sveltekit/content-routes.d.ts +80 -0
  106. package/dist/sveltekit/content-routes.d.ts.map +1 -0
  107. package/dist/sveltekit/content-routes.js +183 -0
  108. package/dist/sveltekit/editors-routes.d.ts +24 -0
  109. package/dist/sveltekit/editors-routes.d.ts.map +1 -0
  110. package/dist/sveltekit/editors-routes.js +73 -0
  111. package/dist/sveltekit/guard.d.ts +9 -0
  112. package/dist/sveltekit/guard.d.ts.map +1 -0
  113. package/dist/sveltekit/guard.js +43 -0
  114. package/dist/sveltekit/health.d.ts +19 -0
  115. package/dist/sveltekit/health.d.ts.map +1 -0
  116. package/dist/sveltekit/health.js +12 -0
  117. package/dist/sveltekit/index.d.ts +9 -173
  118. package/dist/sveltekit/index.d.ts.map +1 -1
  119. package/dist/sveltekit/index.js +8 -348
  120. package/dist/sveltekit/nav-routes.d.ts +30 -0
  121. package/dist/sveltekit/nav-routes.d.ts.map +1 -0
  122. package/dist/sveltekit/nav-routes.js +103 -0
  123. package/dist/sveltekit/types.d.ts +32 -0
  124. package/dist/sveltekit/types.d.ts.map +1 -0
  125. package/dist/sveltekit/types.js +1 -0
  126. package/package.json +33 -57
  127. package/src/lib/auth/crypto.ts +37 -0
  128. package/src/lib/auth/store.ts +158 -0
  129. package/src/lib/auth/types.ts +27 -0
  130. package/src/lib/components/AdminLayout.svelte +58 -164
  131. package/src/lib/components/ComponentPalette.svelte +36 -20
  132. package/src/lib/components/ConceptList.svelte +81 -0
  133. package/src/lib/components/ConfirmPage.svelte +23 -20
  134. package/src/lib/components/EditPage.svelte +155 -136
  135. package/src/lib/components/LoginPage.svelte +42 -52
  136. package/src/lib/components/ManageEditors.svelte +81 -0
  137. package/src/lib/components/MarkdownEditor.svelte +81 -0
  138. package/src/lib/components/NavTree.svelte +73 -63
  139. package/src/lib/components/cairn-admin.css +42 -0
  140. package/src/lib/components/index.ts +5 -4
  141. package/src/lib/content/compose.ts +39 -0
  142. package/src/lib/content/concepts.ts +57 -0
  143. package/src/lib/content/frontmatter.ts +71 -0
  144. package/src/lib/content/ids.ts +38 -0
  145. package/src/lib/content/types.ts +235 -0
  146. package/src/lib/content/validate.ts +51 -0
  147. package/src/lib/email.ts +52 -38
  148. package/src/lib/env.ts +32 -0
  149. package/src/lib/github/credentials.ts +27 -0
  150. package/src/lib/github/repo.ts +138 -0
  151. package/src/lib/github/signing.ts +97 -0
  152. package/src/lib/github/types.ts +46 -0
  153. package/src/lib/index.ts +86 -10
  154. package/src/lib/{nav.ts → nav/site-config.ts} +31 -24
  155. package/src/lib/render/glyph.ts +6 -6
  156. package/src/lib/render/index.ts +6 -6
  157. package/src/lib/render/pipeline.ts +23 -22
  158. package/src/lib/render/registry.ts +35 -26
  159. package/src/lib/render/rehype-dispatch.ts +58 -56
  160. package/src/lib/render/remark-directives.ts +46 -46
  161. package/src/lib/render/sanitize.ts +27 -0
  162. package/src/lib/sveltekit/auth-routes.ts +107 -0
  163. package/src/lib/sveltekit/content-routes.ts +261 -0
  164. package/src/lib/sveltekit/editors-routes.ts +82 -0
  165. package/src/lib/sveltekit/guard.ts +47 -0
  166. package/src/lib/sveltekit/health.ts +24 -0
  167. package/src/lib/sveltekit/index.ts +19 -512
  168. package/src/lib/sveltekit/nav-routes.ts +139 -0
  169. package/src/lib/sveltekit/types.ts +33 -0
  170. package/dist/adapter.d.ts +0 -93
  171. package/dist/adapter.d.ts.map +0 -1
  172. package/dist/adapter.js +0 -30
  173. package/dist/auth/admins.d.ts +0 -33
  174. package/dist/auth/admins.d.ts.map +0 -1
  175. package/dist/auth/admins.js +0 -90
  176. package/dist/auth/capabilities.d.ts +0 -7
  177. package/dist/auth/capabilities.d.ts.map +0 -1
  178. package/dist/auth/capabilities.js +0 -26
  179. package/dist/auth/config.d.ts +0 -2097
  180. package/dist/auth/config.d.ts.map +0 -1
  181. package/dist/auth/config.js +0 -78
  182. package/dist/auth/guard.d.ts +0 -34
  183. package/dist/auth/guard.d.ts.map +0 -1
  184. package/dist/auth/guard.js +0 -47
  185. package/dist/auth/index.d.ts +0 -5
  186. package/dist/auth/index.d.ts.map +0 -1
  187. package/dist/auth/index.js +0 -7
  188. package/dist/auth/schema.d.ts +0 -750
  189. package/dist/auth/schema.d.ts.map +0 -1
  190. package/dist/auth/schema.js +0 -93
  191. package/dist/carta.d.ts +0 -39
  192. package/dist/carta.d.ts.map +0 -1
  193. package/dist/carta.js +0 -30
  194. package/dist/components/CollectionList.svelte +0 -96
  195. package/dist/components/CollectionList.svelte.d.ts +0 -8
  196. package/dist/components/CollectionList.svelte.d.ts.map +0 -1
  197. package/dist/components/ManageAdmins.svelte +0 -84
  198. package/dist/components/ManageAdmins.svelte.d.ts +0 -10
  199. package/dist/components/ManageAdmins.svelte.d.ts.map +0 -1
  200. package/dist/content.d.ts +0 -3
  201. package/dist/content.d.ts.map +0 -1
  202. package/dist/content.js +0 -10
  203. package/dist/editor.d.ts +0 -25
  204. package/dist/editor.d.ts.map +0 -1
  205. package/dist/editor.js +0 -20
  206. package/dist/frontmatter.d.ts +0 -3
  207. package/dist/frontmatter.d.ts.map +0 -1
  208. package/dist/frontmatter.js +0 -16
  209. package/dist/github.d.ts +0 -72
  210. package/dist/github.d.ts.map +0 -1
  211. package/dist/github.js +0 -171
  212. package/dist/nav.d.ts.map +0 -1
  213. package/dist/slug.d.ts +0 -7
  214. package/dist/slug.d.ts.map +0 -1
  215. package/dist/slug.js +0 -15
  216. package/dist/utils.d.ts +0 -3
  217. package/dist/utils.d.ts.map +0 -1
  218. package/dist/utils.js +0 -11
  219. package/src/lib/adapter.ts +0 -144
  220. package/src/lib/auth/admins.ts +0 -106
  221. package/src/lib/auth/capabilities.ts +0 -35
  222. package/src/lib/auth/config.ts +0 -108
  223. package/src/lib/auth/guard.ts +0 -60
  224. package/src/lib/auth/index.ts +0 -7
  225. package/src/lib/auth/schema.ts +0 -112
  226. package/src/lib/carta.ts +0 -59
  227. package/src/lib/components/CollectionList.svelte +0 -96
  228. package/src/lib/components/ManageAdmins.svelte +0 -84
  229. package/src/lib/content.ts +0 -11
  230. package/src/lib/editor.ts +0 -38
  231. package/src/lib/frontmatter.ts +0 -17
  232. package/src/lib/github.ts +0 -220
  233. package/src/lib/slug.ts +0 -16
  234. package/src/lib/utils.ts +0 -12
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/lib/auth/schema.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBf,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBnB,CAAC;AAEF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BnB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBxB,CAAC;AAEF,eAAO,MAAM,aAAa;;;EAGvB,CAAC;AAEJ,eAAO,MAAM,gBAAgB;;EAK1B,CAAC;AAEJ,eAAO,MAAM,gBAAgB;;EAK1B,CAAC"}
@@ -1,93 +0,0 @@
1
- import { relations, sql } from "drizzle-orm";
2
- import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core";
3
- export const user = sqliteTable("user", {
4
- id: text("id").primaryKey(),
5
- name: text("name").notNull(),
6
- email: text("email").notNull().unique(),
7
- emailVerified: integer("email_verified", { mode: "boolean" })
8
- .default(false)
9
- .notNull(),
10
- image: text("image"),
11
- createdAt: integer("created_at", { mode: "timestamp_ms" })
12
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
13
- .notNull(),
14
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
15
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
16
- .$onUpdate(() => /* @__PURE__ */ new Date())
17
- .notNull(),
18
- role: text("role"),
19
- banned: integer("banned", { mode: "boolean" }).default(false),
20
- banReason: text("ban_reason"),
21
- banExpires: integer("ban_expires", { mode: "timestamp_ms" }),
22
- });
23
- export const session = sqliteTable("session", {
24
- id: text("id").primaryKey(),
25
- expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
26
- token: text("token").notNull().unique(),
27
- createdAt: integer("created_at", { mode: "timestamp_ms" })
28
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
29
- .notNull(),
30
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
31
- .$onUpdate(() => /* @__PURE__ */ new Date())
32
- .notNull(),
33
- ipAddress: text("ip_address"),
34
- userAgent: text("user_agent"),
35
- userId: text("user_id")
36
- .notNull()
37
- .references(() => user.id, { onDelete: "cascade" }),
38
- impersonatedBy: text("impersonated_by"),
39
- }, (table) => [index("session_userId_idx").on(table.userId)]);
40
- export const account = sqliteTable("account", {
41
- id: text("id").primaryKey(),
42
- accountId: text("account_id").notNull(),
43
- providerId: text("provider_id").notNull(),
44
- userId: text("user_id")
45
- .notNull()
46
- .references(() => user.id, { onDelete: "cascade" }),
47
- accessToken: text("access_token"),
48
- refreshToken: text("refresh_token"),
49
- idToken: text("id_token"),
50
- accessTokenExpiresAt: integer("access_token_expires_at", {
51
- mode: "timestamp_ms",
52
- }),
53
- refreshTokenExpiresAt: integer("refresh_token_expires_at", {
54
- mode: "timestamp_ms",
55
- }),
56
- scope: text("scope"),
57
- password: text("password"),
58
- createdAt: integer("created_at", { mode: "timestamp_ms" })
59
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
60
- .notNull(),
61
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
62
- .$onUpdate(() => /* @__PURE__ */ new Date())
63
- .notNull(),
64
- }, (table) => [index("account_userId_idx").on(table.userId)]);
65
- export const verification = sqliteTable("verification", {
66
- id: text("id").primaryKey(),
67
- identifier: text("identifier").notNull(),
68
- value: text("value").notNull(),
69
- expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
70
- createdAt: integer("created_at", { mode: "timestamp_ms" })
71
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
72
- .notNull(),
73
- updatedAt: integer("updated_at", { mode: "timestamp_ms" })
74
- .default(sql `(cast(unixepoch('subsecond') * 1000 as integer))`)
75
- .$onUpdate(() => /* @__PURE__ */ new Date())
76
- .notNull(),
77
- }, (table) => [index("verification_identifier_idx").on(table.identifier)]);
78
- export const userRelations = relations(user, ({ many }) => ({
79
- sessions: many(session),
80
- accounts: many(account),
81
- }));
82
- export const sessionRelations = relations(session, ({ one }) => ({
83
- user: one(user, {
84
- fields: [session.userId],
85
- references: [user.id],
86
- }),
87
- }));
88
- export const accountRelations = relations(account, ({ one }) => ({
89
- user: one(user, {
90
- fields: [account.userId],
91
- references: [user.id],
92
- }),
93
- }));
package/dist/carta.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import type { Pluggable, Processor } from 'unified';
2
- export interface PreviewPlugins {
3
- /** remark plugins, injected after gfm and before remark-rehype. */
4
- remarkPlugins: Pluggable[];
5
- /** rehype plugins, injected after remark-rehype. */
6
- rehypePlugins: Pluggable[];
7
- }
8
- interface PreviewTransformer {
9
- execution: 'sync';
10
- type: 'remark' | 'rehype';
11
- transform: (ctx: {
12
- processor: Processor;
13
- }) => void;
14
- }
15
- /**
16
- * Map the site's plugin set to Carta sync transformers, remark phase before rehype.
17
- * Carta's processor is remarkParse → gfm → [remark] → remark-rehype → [rehype] → stringify,
18
- * so this ordering reproduces render.ts exactly. Pure (no Carta) so it is unit-testable.
19
- */
20
- export declare function previewTransformers({ remarkPlugins, rehypePlugins }: PreviewPlugins): PreviewTransformer[];
21
- /** Minimal Options subset we populate (avoids importing carta-md, which re-exports Svelte components). */
22
- interface PreviewCartaOptions {
23
- sanitizer: false;
24
- rehypeOptions: {
25
- allowDangerousHtml: boolean;
26
- };
27
- extensions: Array<{
28
- transformers: PreviewTransformer[];
29
- }>;
30
- }
31
- /**
32
- * Carta options for a render-only preview: site plugins wired in, raw HTML allowed, no
33
- * sanitizer. Authors are trusted and the directive pipeline emits intentional raw HTML
34
- * (render.ts uses allowDangerousHtml + rehype-raw); sanitizing here would strip EC
35
- * primitives. The Svelte component passes this to `new Carta(...)`.
36
- */
37
- export declare function previewCartaOptions(plugins: PreviewPlugins): PreviewCartaOptions;
38
- export {};
39
- //# sourceMappingURL=carta.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"carta.d.ts","sourceRoot":"","sources":["../src/lib/carta.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,aAAa,EAAE,SAAS,EAAE,CAAC;IAC3B,oDAAoD;IACpD,aAAa,EAAE,SAAS,EAAE,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,SAAS,EAAE,CAAC,GAAG,EAAE;QAAE,SAAS,EAAE,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;CACpD;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,cAAc,GAAG,kBAAkB,EAAE,CAE1G;AAED,0GAA0G;AAC1G,UAAU,mBAAmB;IAC3B,SAAS,EAAE,KAAK,CAAC;IACjB,aAAa,EAAE;QAAE,kBAAkB,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,kBAAkB,EAAE,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,mBAAmB,CAMhF"}
package/dist/carta.js DELETED
@@ -1,30 +0,0 @@
1
- function phase(plugins, type) {
2
- return plugins.map((plugin) => ({
3
- execution: 'sync',
4
- type,
5
- transform: ({ processor }) => {
6
- processor.use([plugin]);
7
- },
8
- }));
9
- }
10
- /**
11
- * Map the site's plugin set to Carta sync transformers, remark phase before rehype.
12
- * Carta's processor is remarkParse → gfm → [remark] → remark-rehype → [rehype] → stringify,
13
- * so this ordering reproduces render.ts exactly. Pure (no Carta) so it is unit-testable.
14
- */
15
- export function previewTransformers({ remarkPlugins, rehypePlugins }) {
16
- return [...phase(remarkPlugins, 'remark'), ...phase(rehypePlugins, 'rehype')];
17
- }
18
- /**
19
- * Carta options for a render-only preview: site plugins wired in, raw HTML allowed, no
20
- * sanitizer. Authors are trusted and the directive pipeline emits intentional raw HTML
21
- * (render.ts uses allowDangerousHtml + rehype-raw); sanitizing here would strip EC
22
- * primitives. The Svelte component passes this to `new Carta(...)`.
23
- */
24
- export function previewCartaOptions(plugins) {
25
- return {
26
- sanitizer: false,
27
- rehypeOptions: { allowDangerousHtml: true },
28
- extensions: [{ transformers: previewTransformers(plugins) }],
29
- };
30
- }
@@ -1,96 +0,0 @@
1
- <script lang="ts">
2
- // One collection's entries: a table (title, date, draft badge) linking into the editor, plus a
3
- // collapsible "New entry" form. The author types a title; the slug stem derives from it (R4) and
4
- // stays editable. A story collection also collects a date, which createEntry forwards so the new
5
- // entry opens with its date set. Placeholders differ by kind. The shell (AdminLayout) owns the
6
- // chrome and nav; this renders only the body.
7
- import type { CollectionListData } from '../sveltekit';
8
- import { slugify } from '../slug';
9
-
10
- let { data }: { data: CollectionListData } = $props();
11
-
12
- let title = $state('');
13
- let slug = $state('');
14
- let slugEdited = $state(false);
15
-
16
- // Keep the slug in sync with the title until the author edits the slug directly.
17
- function onTitleInput(value: string) {
18
- title = value;
19
- if (!slugEdited) slug = slugify(value);
20
- }
21
-
22
- const slugPlaceholder = $derived(data.kind === 'page' ? 'about-us' : '2026-05-my-entry');
23
- </script>
24
-
25
- <div class="flex items-center justify-between gap-4">
26
- <h1 class="text-2xl font-bold">{data.label}</h1>
27
- {#if data.canCreate}
28
- <details class="dropdown dropdown-end">
29
- <summary class="btn btn-primary btn-sm">New entry</summary>
30
- <form
31
- method="POST"
32
- action="?/create"
33
- class="dropdown-content z-10 mt-2 flex w-80 flex-col gap-2 rounded-box border border-base-300 bg-base-100 p-4 shadow"
34
- >
35
- <label class="flex flex-col gap-1">
36
- <span class="text-sm font-medium">Title</span>
37
- <input
38
- type="text"
39
- value={title}
40
- oninput={(e) => onTitleInput(e.currentTarget.value)}
41
- placeholder="A human title"
42
- class="input w-full"
43
- />
44
- </label>
45
-
46
- {#if data.kind === 'story'}
47
- <label class="flex flex-col gap-1">
48
- <span class="text-sm font-medium">Date</span>
49
- <input type="date" name="date" class="input w-full" />
50
- </label>
51
- {/if}
52
-
53
- <label class="flex flex-col gap-1">
54
- <span class="text-sm font-medium">Slug</span>
55
- <input
56
- type="text"
57
- name="id"
58
- required
59
- bind:value={slug}
60
- oninput={() => (slugEdited = true)}
61
- placeholder={slugPlaceholder}
62
- pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?"
63
- class="input w-full"
64
- />
65
- <span class="text-xs opacity-60">Lowercase letters, numbers, and hyphens. Becomes the filename.</span>
66
- </label>
67
-
68
- <button type="submit" class="btn btn-primary btn-sm">Create &amp; edit</button>
69
- </form>
70
- </details>
71
- {/if}
72
- </div>
73
-
74
- {#if data.formError}
75
- <div class="alert alert-error mt-4"><span>{data.formError}</span></div>
76
- {/if}
77
-
78
- {#if data.error}
79
- <div class="alert alert-warning mt-6">Couldn't load {data.label.toLowerCase()}: {data.error}</div>
80
- {:else if data.entries.length === 0}
81
- <p class="mt-6 opacity-60">No entries yet.</p>
82
- {:else}
83
- <ul class="menu mt-6 rounded-box border border-base-300 bg-base-100 p-2">
84
- {#each data.entries as entry (entry.path)}
85
- <li>
86
- <a href="/admin/edit/{data.type}/{entry.id}" class="flex items-center justify-between gap-3">
87
- <span class="flex items-center gap-2">
88
- <span>{entry.title}</span>
89
- {#if entry.draft}<span class="badge badge-warning badge-sm">Draft</span>{/if}
90
- </span>
91
- {#if entry.date}<span class="text-xs opacity-60">{entry.date}</span>{/if}
92
- </a>
93
- </li>
94
- {/each}
95
- </ul>
96
- {/if}
@@ -1,8 +0,0 @@
1
- import type { CollectionListData } from '../sveltekit';
2
- type $$ComponentProps = {
3
- data: CollectionListData;
4
- };
5
- declare const CollectionList: import("svelte").Component<$$ComponentProps, {}, "">;
6
- type CollectionList = ReturnType<typeof CollectionList>;
7
- export default CollectionList;
8
- //# sourceMappingURL=CollectionList.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CollectionList.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/CollectionList.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGtD,KAAK,gBAAgB,GAAI;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAiFvD,QAAA,MAAM,cAAc,sDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -1,84 +0,0 @@
1
- <script lang="ts">
2
- // Owner-gated editor management: list the allowlist, change roles, remove editors, add new
3
- // ones. Reuses the same neutral DaisyUI chrome as the rest of the admin (panels, alerts,
4
- // table, buttons). Data comes from `adminsLoad` merged with `adminLayoutLoad` (siteName);
5
- // mutations post to the page's named form actions (`?/add`, `?/remove`, `?/setRole`).
6
- import type { AdminsData } from '../auth';
7
-
8
- interface Props {
9
- data: AdminsData & { siteName: string };
10
- }
11
- let { data }: Props = $props();
12
- </script>
13
-
14
- <svelte:head>
15
- <title>Editors · {data.siteName} CMS</title>
16
- </svelte:head>
17
-
18
- <div>
19
- <h1 class="text-2xl font-bold">Editors</h1>
20
- <p class="text-sm opacity-60">Who can sign in to {data.siteName} CMS.</p>
21
- </div>
22
-
23
- {#if data.saved}
24
- <div class="alert alert-success mt-6"><span>Allowlist updated.</span></div>
25
- {:else if data.error}
26
- <div class="alert alert-error mt-6"><span>{data.error}</span></div>
27
- {/if}
28
-
29
- <div class="mt-6 overflow-x-auto rounded-box border border-base-300 bg-base-100">
30
- <table class="table">
31
- <thead>
32
- <tr><th>Name</th><th>Email</th><th>Role</th><th class="text-right">Actions</th></tr>
33
- </thead>
34
- <tbody>
35
- {#each data.admins as admin (admin.email)}
36
- {@const isSelf = admin.email === data.self}
37
- <tr>
38
- <td class="font-medium">{admin.name}</td>
39
- <td class="opacity-70">{admin.email}{#if isSelf}<span class="ml-1 opacity-50">(you)</span>{/if}</td>
40
- <td>
41
- <span class="badge {admin.role === 'owner' ? 'badge-primary' : 'badge-ghost'}">{admin.role}</span>
42
- </td>
43
- <td>
44
- <div class="flex justify-end gap-2">
45
- <!-- Flip role. Disabled for yourself so you can't demote the last owner out. -->
46
- <form method="POST" action="?/setRole">
47
- <input type="hidden" name="email" value={admin.email} />
48
- <input type="hidden" name="role" value={admin.role === 'owner' ? 'editor' : 'owner'} />
49
- <button type="submit" class="btn btn-ghost btn-xs" disabled={isSelf}>
50
- Make {admin.role === 'owner' ? 'editor' : 'owner'}
51
- </button>
52
- </form>
53
- <form method="POST" action="?/remove">
54
- <input type="hidden" name="email" value={admin.email} />
55
- <button type="submit" class="btn btn-ghost btn-xs text-error" disabled={isSelf}>Remove</button>
56
- </form>
57
- </div>
58
- </td>
59
- </tr>
60
- {/each}
61
- </tbody>
62
- </table>
63
- </div>
64
-
65
- <form method="POST" action="?/add"
66
- class="mt-8 grid gap-4 rounded-box border border-base-300 bg-base-100 p-6 sm:grid-cols-[1fr_1fr_auto_auto] sm:items-end">
67
- <label class="flex flex-col gap-1">
68
- <span class="text-sm font-medium">Email</span>
69
- <input type="email" name="email" required autocomplete="off" placeholder="you@example.com"
70
- class="input w-full" />
71
- </label>
72
- <label class="flex flex-col gap-1">
73
- <span class="text-sm font-medium">Name</span>
74
- <input type="text" name="name" required placeholder="Display name" class="input w-full" />
75
- </label>
76
- <label class="flex flex-col gap-1">
77
- <span class="text-sm font-medium">Role</span>
78
- <select name="role" class="select">
79
- <option value="editor">editor</option>
80
- <option value="owner">owner</option>
81
- </select>
82
- </label>
83
- <button type="submit" class="btn btn-primary">Add editor</button>
84
- </form>
@@ -1,10 +0,0 @@
1
- import type { AdminsData } from '../auth';
2
- interface Props {
3
- data: AdminsData & {
4
- siteName: string;
5
- };
6
- }
7
- declare const ManageAdmins: import("svelte").Component<Props, {}, "">;
8
- type ManageAdmins = ReturnType<typeof ManageAdmins>;
9
- export default ManageAdmins;
10
- //# sourceMappingURL=ManageAdmins.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ManageAdmins.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/ManageAdmins.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGxC,UAAU,KAAK;IACb,IAAI,EAAE,UAAU,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAmFH,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
package/dist/content.d.ts DELETED
@@ -1,3 +0,0 @@
1
- /** Serialize frontmatter data + markdown body back into a file string. */
2
- export declare function serializeMarkdown(frontmatter: object, body: string): string;
3
- //# sourceMappingURL=content.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/lib/content.ts"],"names":[],"mappings":"AAOA,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3E"}
package/dist/content.js DELETED
@@ -1,10 +0,0 @@
1
- // cairn-core: reassemble a markdown file from frontmatter + body for committing.
2
- //
3
- // The inverse of the gray-matter parse the edit loader does on read. Kept as its own seam
4
- // so a site adapter can own the on-disk serialization contract (quoting, key order)
5
- // without the save endpoint reaching for gray-matter directly.
6
- import matter from 'gray-matter';
7
- /** Serialize frontmatter data + markdown body back into a file string. */
8
- export function serializeMarkdown(frontmatter, body) {
9
- return matter.stringify(body, frontmatter);
10
- }
package/dist/editor.d.ts DELETED
@@ -1,25 +0,0 @@
1
- interface CartaInput {
2
- getSelection(): {
3
- start: number;
4
- end: number;
5
- direction: string;
6
- slice: string;
7
- };
8
- insertAt(position: number, text: string): void;
9
- }
10
- interface CartaLike {
11
- input?: CartaInput;
12
- }
13
- /** The programmatic editing surface the admin relies on. */
14
- export interface MarkdownEditor {
15
- /** Insert a component or template at the current cursor position. */
16
- insertComponent(template: string): void;
17
- }
18
- /**
19
- * Wrap a Carta instance as a MarkdownEditor. Takes a getter (not the instance) because the
20
- * EditPage component creates the Carta instance once and `carta.input` is only populated after
21
- * the editor mounts; reading it lazily at call time avoids capturing an undefined `input`.
22
- */
23
- export declare function cartaEditor(getCarta: () => CartaLike): MarkdownEditor;
24
- export {};
25
- //# sourceMappingURL=editor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../src/lib/editor.ts"],"names":[],"mappings":"AAQA,UAAU,UAAU;IAClB,YAAY,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjF,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,SAAS,GAAG,cAAc,CASrE"}
package/dist/editor.js DELETED
@@ -1,20 +0,0 @@
1
- // cairn-core: the editor cursor seam (decision P3). The component palette and any later insert
2
- // control talk to MarkdownEditor, never to Carta directly, so a swap to a different editing
3
- // engine is contained to this file. Verified against carta-md@4.11: `input.getSelection()` and
4
- // `input.insertAt(pos, text)` are public on the InputEnhancer.
5
- /**
6
- * Wrap a Carta instance as a MarkdownEditor. Takes a getter (not the instance) because the
7
- * EditPage component creates the Carta instance once and `carta.input` is only populated after
8
- * the editor mounts; reading it lazily at call time avoids capturing an undefined `input`.
9
- */
10
- export function cartaEditor(getCarta) {
11
- return {
12
- insertComponent(template) {
13
- const input = getCarta().input;
14
- if (!input)
15
- return; // editor not mounted yet; nothing to insert into
16
- const { start } = input.getSelection();
17
- input.insertAt(start, template);
18
- },
19
- };
20
- }
@@ -1,3 +0,0 @@
1
- /** A frontmatter date value (Date or string) to the `YYYY-MM-DD` an `<input type="date">` expects. */
2
- export declare function dateInputValue(value: unknown): string;
3
- //# sourceMappingURL=frontmatter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/lib/frontmatter.ts"],"names":[],"mappings":"AAMA,sGAAsG;AACtG,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASrD"}
@@ -1,16 +0,0 @@
1
- // cairn-core: coerce a frontmatter value to the YYYY-MM-DD string an <input type="date"> wants.
2
- // gray-matter parses an unquoted YAML date (date: 2026-05-14) into a JS Date, so a string-only
3
- // read leaves the date input empty and drops the date on save. This normalizes a Date or an
4
- // ISO-ish string to YYYY-MM-DD. A parsed YAML date is UTC midnight, so slicing the ISO string
5
- // avoids a local-timezone shift. Internal (not re-exported from the barrel), like utils.ts.
6
- /** A frontmatter date value (Date or string) to the `YYYY-MM-DD` an `<input type="date">` expects. */
7
- export function dateInputValue(value) {
8
- if (value instanceof Date) {
9
- return Number.isNaN(value.getTime()) ? '' : value.toISOString().slice(0, 10);
10
- }
11
- if (typeof value === 'string') {
12
- const match = value.match(/^\d{4}-\d{2}-\d{2}/);
13
- return match ? match[0] : '';
14
- }
15
- return '';
16
- }
package/dist/github.d.ts DELETED
@@ -1,72 +0,0 @@
1
- export interface RepoRef {
2
- owner: string;
3
- repo: string;
4
- branch: string;
5
- }
6
- /** A markdown file in a collection directory. `id` is the slug (filename without `.md`). */
7
- export interface RepoFile {
8
- id: string;
9
- name: string;
10
- path: string;
11
- }
12
- /** Build the contents-API URL for a repo path, pinned to the configured branch. */
13
- export declare function contentsUrl(repo: RepoRef, path: string): string;
14
- interface ContentsEntry {
15
- name: string;
16
- path: string;
17
- type: string;
18
- }
19
- /** Keep only markdown files from a contents-API directory listing, newest id first. */
20
- export declare function markdownFiles(entries: ContentsEntry[]): RepoFile[];
21
- /** List the markdown files in a collection directory. */
22
- export declare function listMarkdown(repo: RepoRef, dir: string, token?: string): Promise<RepoFile[]>;
23
- /** Fetch a file's raw markdown, or null if it does not exist. */
24
- export declare function readRaw(repo: RepoRef, path: string, token?: string): Promise<string | null>;
25
- /** Mint a GitHub App JWT (RS256), valid ~9 min, with `iat` backdated for clock skew. */
26
- export declare function appJwt(appId: string, privateKeyPem: string): Promise<string>;
27
- export interface AppCredentials {
28
- appId: string;
29
- installationId: string;
30
- /** The stored GITHUB_APP_PRIVATE_KEY_B64: base64 of the PEM, single line. */
31
- privateKeyB64: string;
32
- }
33
- /** Exchange the App JWT for a short-lived installation access token. */
34
- export declare function installationToken(creds: AppCredentials): Promise<string>;
35
- /** The current blob sha for a path, or null if the file does not yet exist. */
36
- export declare function fileSha(repo: RepoRef, path: string, token: string): Promise<string | null>;
37
- export interface CommitAuthor {
38
- name: string;
39
- email: string;
40
- }
41
- /**
42
- * A concurrent edit lost the SHA race (C3): the file changed between the read and the PUT,
43
- * from another editor or the site's own CI. Thrown so callers can fail safe (re-fetch and ask
44
- * the editor to reapply) instead of surfacing a raw 409. Defined and caught inside the package
45
- * so `instanceof` is reliable (no peer-boundary identity split, unlike kit's `redirect`/`error`).
46
- */
47
- export declare class CommitConflictError extends Error {
48
- readonly path: string;
49
- constructor(path: string);
50
- }
51
- /**
52
- * Commit `content` to `path` on the configured branch via the contents API. Author is the
53
- * editor; committer is omitted so GitHub attributes it to the App (cairn-cms[bot]). Updates
54
- * the file in place when it exists (passing its sha), creates it otherwise. Returns the
55
- * commit sha. A stale-sha 409 (someone committed in between) becomes a `CommitConflictError`.
56
- */
57
- export declare function commitFile(repo: RepoRef, path: string, content: string, opts: {
58
- message: string;
59
- author: CommitAuthor;
60
- }, token: string): Promise<string>;
61
- /**
62
- * Deploy-time self-test for the GitHub App signer (M2): sign a dummy JWT with the configured
63
- * private key. Exercises the brittle PKCS#1→PKCS#8 conversion + Web Crypto import/sign without
64
- * any network call or secret in the result, so `/admin/healthz` catches a bad/rotated key
65
- * before an editor's save fails. Returns `{ ok: false, detail }` rather than throwing.
66
- */
67
- export declare function signingSelfTest(appId: string, privateKeyB64: string): Promise<{
68
- ok: boolean;
69
- detail?: string;
70
- }>;
71
- export {};
72
- //# sourceMappingURL=github.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/lib/github.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4FAA4F;AAC5F,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAcD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAE,CAKlE;AAED,yDAAyD;AACzD,wBAAsB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAIlG;AAED,iEAAiE;AACjE,wBAAsB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKjG;AAqCD,wFAAwF;AACxF,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAclF;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wEAAwE;AACxE,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ9E;AAOD,+EAA+E;AAC/E,wBAAsB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKhG;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAIzC;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,EAC/C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQrH"}