@prenta/core 8.9.2 → 8.11.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 (294) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/actions.d.ts +25 -0
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +51 -4
  5. package/dist/actions.js.map +1 -1
  6. package/dist/ai/batch-links.d.ts +105 -0
  7. package/dist/ai/batch-links.d.ts.map +1 -0
  8. package/dist/ai/batch-links.js +667 -0
  9. package/dist/ai/batch-links.js.map +1 -0
  10. package/dist/ai/batch-list.d.ts +127 -4
  11. package/dist/ai/batch-list.d.ts.map +1 -1
  12. package/dist/ai/batch-list.js +250 -14
  13. package/dist/ai/batch-list.js.map +1 -1
  14. package/dist/ai/providers/http.d.ts +4 -0
  15. package/dist/ai/providers/http.d.ts.map +1 -1
  16. package/dist/ai/providers/http.js +9 -8
  17. package/dist/ai/providers/http.js.map +1 -1
  18. package/dist/ai/tasks/editor-text.d.ts +39 -0
  19. package/dist/ai/tasks/editor-text.d.ts.map +1 -0
  20. package/dist/ai/tasks/editor-text.js +45 -0
  21. package/dist/ai/tasks/editor-text.js.map +1 -0
  22. package/dist/ai/tasks/link-embeddings.d.ts +22 -0
  23. package/dist/ai/tasks/link-embeddings.d.ts.map +1 -1
  24. package/dist/ai/tasks/link-embeddings.js +24 -10
  25. package/dist/ai/tasks/link-embeddings.js.map +1 -1
  26. package/dist/ai/usage.d.ts +7 -0
  27. package/dist/ai/usage.d.ts.map +1 -1
  28. package/dist/ai/usage.js +11 -0
  29. package/dist/ai/usage.js.map +1 -1
  30. package/dist/api/guarded-db.d.ts +6 -0
  31. package/dist/api/guarded-db.d.ts.map +1 -1
  32. package/dist/api/guarded-db.js +13 -1
  33. package/dist/api/guarded-db.js.map +1 -1
  34. package/dist/api/handlers.d.ts.map +1 -1
  35. package/dist/api/handlers.js +2 -0
  36. package/dist/api/handlers.js.map +1 -1
  37. package/dist/api/openapi.d.ts.map +1 -1
  38. package/dist/api/openapi.js +103 -0
  39. package/dist/api/openapi.js.map +1 -1
  40. package/dist/api/route-helpers/forms.d.ts.map +1 -1
  41. package/dist/api/route-helpers/forms.js +7 -1
  42. package/dist/api/route-helpers/forms.js.map +1 -1
  43. package/dist/api/routes/ai-authoring.d.ts.map +1 -1
  44. package/dist/api/routes/ai-authoring.js +1 -0
  45. package/dist/api/routes/ai-authoring.js.map +1 -1
  46. package/dist/api/routes/ai-seo.d.ts.map +1 -1
  47. package/dist/api/routes/ai-seo.js +20 -18
  48. package/dist/api/routes/ai-seo.js.map +1 -1
  49. package/dist/api/routes/media.d.ts.map +1 -1
  50. package/dist/api/routes/media.js +3 -1
  51. package/dist/api/routes/media.js.map +1 -1
  52. package/dist/api/routes/scheduling.d.ts.map +1 -1
  53. package/dist/api/routes/scheduling.js +33 -2
  54. package/dist/api/routes/scheduling.js.map +1 -1
  55. package/dist/appearance/color.d.ts +17 -0
  56. package/dist/appearance/color.d.ts.map +1 -1
  57. package/dist/appearance/color.js +162 -1
  58. package/dist/appearance/color.js.map +1 -1
  59. package/dist/appearance/index.d.ts +3 -3
  60. package/dist/appearance/index.d.ts.map +1 -1
  61. package/dist/appearance/index.js +2 -2
  62. package/dist/appearance/index.js.map +1 -1
  63. package/dist/appearance/resolve.d.ts.map +1 -1
  64. package/dist/appearance/resolve.js +4 -2
  65. package/dist/appearance/resolve.js.map +1 -1
  66. package/dist/appearance/theme-tokens.d.ts +60 -11
  67. package/dist/appearance/theme-tokens.d.ts.map +1 -1
  68. package/dist/appearance/theme-tokens.js +184 -175
  69. package/dist/appearance/theme-tokens.js.map +1 -1
  70. package/dist/appearance/types.d.ts +16 -2
  71. package/dist/appearance/types.d.ts.map +1 -1
  72. package/dist/astro-site.d.ts +1 -11
  73. package/dist/astro-site.d.ts.map +1 -1
  74. package/dist/astro-site.js +4 -0
  75. package/dist/astro-site.js.map +1 -1
  76. package/dist/auth/team.d.ts +1 -0
  77. package/dist/auth/team.d.ts.map +1 -1
  78. package/dist/auth/team.js +1 -1
  79. package/dist/auth/team.js.map +1 -1
  80. package/dist/cache/http.d.ts +20 -0
  81. package/dist/cache/http.d.ts.map +1 -1
  82. package/dist/cache/http.js +42 -0
  83. package/dist/cache/http.js.map +1 -1
  84. package/dist/chrome/announcement.d.ts +30 -0
  85. package/dist/chrome/announcement.d.ts.map +1 -0
  86. package/dist/chrome/announcement.js +190 -0
  87. package/dist/chrome/announcement.js.map +1 -0
  88. package/dist/chrome/codegen.d.ts +17 -0
  89. package/dist/chrome/codegen.d.ts.map +1 -0
  90. package/dist/chrome/codegen.js +96 -0
  91. package/dist/chrome/codegen.js.map +1 -0
  92. package/dist/chrome/contract.d.ts +161 -0
  93. package/dist/chrome/contract.d.ts.map +1 -0
  94. package/dist/chrome/contract.js +2 -0
  95. package/dist/chrome/contract.js.map +1 -0
  96. package/dist/chrome/memory-store.d.ts +15 -0
  97. package/dist/chrome/memory-store.d.ts.map +1 -0
  98. package/dist/chrome/memory-store.js +54 -0
  99. package/dist/chrome/memory-store.js.map +1 -0
  100. package/dist/chrome/overrides.d.ts +25 -0
  101. package/dist/chrome/overrides.d.ts.map +1 -0
  102. package/dist/chrome/overrides.js +180 -0
  103. package/dist/chrome/overrides.js.map +1 -0
  104. package/dist/chrome/parse.d.ts +36 -0
  105. package/dist/chrome/parse.d.ts.map +1 -0
  106. package/dist/chrome/parse.js +277 -0
  107. package/dist/chrome/parse.js.map +1 -0
  108. package/dist/chrome/prisma-store.d.ts +11 -0
  109. package/dist/chrome/prisma-store.d.ts.map +1 -0
  110. package/dist/chrome/prisma-store.js +48 -0
  111. package/dist/chrome/prisma-store.js.map +1 -0
  112. package/dist/chrome/public.d.ts +22 -0
  113. package/dist/chrome/public.d.ts.map +1 -0
  114. package/dist/chrome/public.js +181 -0
  115. package/dist/chrome/public.js.map +1 -0
  116. package/dist/chrome/resolve.d.ts +36 -0
  117. package/dist/chrome/resolve.d.ts.map +1 -0
  118. package/dist/chrome/resolve.js +165 -0
  119. package/dist/chrome/resolve.js.map +1 -0
  120. package/dist/chrome/revalidate.d.ts +9 -0
  121. package/dist/chrome/revalidate.d.ts.map +1 -0
  122. package/dist/chrome/revalidate.js +51 -0
  123. package/dist/chrome/revalidate.js.map +1 -0
  124. package/dist/chrome/routes.d.ts +14 -0
  125. package/dist/chrome/routes.d.ts.map +1 -0
  126. package/dist/chrome/routes.js +349 -0
  127. package/dist/chrome/routes.js.map +1 -0
  128. package/dist/chrome/schema.d.ts +231 -0
  129. package/dist/chrome/schema.d.ts.map +1 -0
  130. package/dist/chrome/schema.js +73 -0
  131. package/dist/chrome/schema.js.map +1 -0
  132. package/dist/chrome/service.d.ts +76 -0
  133. package/dist/chrome/service.d.ts.map +1 -0
  134. package/dist/chrome/service.js +286 -0
  135. package/dist/chrome/service.js.map +1 -0
  136. package/dist/chrome/settings.d.ts +14 -0
  137. package/dist/chrome/settings.d.ts.map +1 -0
  138. package/dist/chrome/settings.js +142 -0
  139. package/dist/chrome/settings.js.map +1 -0
  140. package/dist/chrome/store.d.ts +48 -0
  141. package/dist/chrome/store.d.ts.map +1 -0
  142. package/dist/chrome/store.js +26 -0
  143. package/dist/chrome/store.js.map +1 -0
  144. package/dist/chrome/values.d.ts +98 -0
  145. package/dist/chrome/values.d.ts.map +1 -0
  146. package/dist/chrome/values.js +491 -0
  147. package/dist/chrome/values.js.map +1 -0
  148. package/dist/config/define.d.ts +2 -0
  149. package/dist/config/define.d.ts.map +1 -1
  150. package/dist/config/define.js +2 -0
  151. package/dist/config/define.js.map +1 -1
  152. package/dist/db/model-types.d.ts +62 -0
  153. package/dist/db/model-types.d.ts.map +1 -1
  154. package/dist/forms/attribution-settings.d.ts +23 -0
  155. package/dist/forms/attribution-settings.d.ts.map +1 -0
  156. package/dist/forms/attribution-settings.js +42 -0
  157. package/dist/forms/attribution-settings.js.map +1 -0
  158. package/dist/forms/attribution.d.ts +5 -1
  159. package/dist/forms/attribution.d.ts.map +1 -1
  160. package/dist/forms/attribution.js +6 -4
  161. package/dist/forms/attribution.js.map +1 -1
  162. package/dist/forms/client-validation.d.ts.map +1 -1
  163. package/dist/forms/client-validation.js +3 -0
  164. package/dist/forms/client-validation.js.map +1 -1
  165. package/dist/forms/form-model.d.ts +109 -0
  166. package/dist/forms/form-model.d.ts.map +1 -0
  167. package/dist/forms/form-model.js +192 -0
  168. package/dist/forms/form-model.js.map +1 -0
  169. package/dist/forms/index.d.ts +2 -2
  170. package/dist/forms/index.d.ts.map +1 -1
  171. package/dist/forms/index.js +1 -1
  172. package/dist/forms/index.js.map +1 -1
  173. package/dist/forms/service.d.ts +19 -1
  174. package/dist/forms/service.d.ts.map +1 -1
  175. package/dist/forms/service.js +152 -0
  176. package/dist/forms/service.js.map +1 -1
  177. package/dist/forms/spam.d.ts +0 -12
  178. package/dist/forms/spam.d.ts.map +1 -1
  179. package/dist/forms/spam.js +30 -0
  180. package/dist/forms/spam.js.map +1 -1
  181. package/dist/forms/submission.d.ts +7 -0
  182. package/dist/forms/submission.d.ts.map +1 -1
  183. package/dist/forms/submission.js +33 -0
  184. package/dist/forms/submission.js.map +1 -1
  185. package/dist/forms/types.d.ts +26 -1
  186. package/dist/forms/types.d.ts.map +1 -1
  187. package/dist/forms/types.js +9 -1
  188. package/dist/forms/types.js.map +1 -1
  189. package/dist/generated/browser.d.ts +35 -3
  190. package/dist/generated/client.d.ts +35 -3
  191. package/dist/generated/internal/class.d.ts +44 -0
  192. package/dist/generated/internal/class.js +4 -4
  193. package/dist/generated/internal/prismaNamespace.d.ts +403 -1
  194. package/dist/generated/internal/prismaNamespace.js +95 -1
  195. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +102 -0
  196. package/dist/generated/internal/prismaNamespaceBrowser.js +95 -1
  197. package/dist/generated/models/ChromeRegion.d.ts +1203 -0
  198. package/dist/generated/models/ChromeRegion.js +1 -0
  199. package/dist/generated/models/Job.d.ts +732 -5
  200. package/dist/generated/models/JobEvent.d.ts +1339 -0
  201. package/dist/generated/models/JobEvent.js +1 -0
  202. package/dist/generated/models/JobReviewItem.d.ts +1470 -0
  203. package/dist/generated/models/JobReviewItem.js +1 -0
  204. package/dist/generated/models/SystemSetting.d.ts +952 -0
  205. package/dist/generated/models/SystemSetting.js +1 -0
  206. package/dist/generated/models.d.ts +4 -0
  207. package/dist/index.d.ts +12 -5
  208. package/dist/index.d.ts.map +1 -1
  209. package/dist/index.js +8 -3
  210. package/dist/index.js.map +1 -1
  211. package/dist/jobs/batch-ai.d.ts +53 -0
  212. package/dist/jobs/batch-ai.d.ts.map +1 -0
  213. package/dist/jobs/batch-ai.js +314 -0
  214. package/dist/jobs/batch-ai.js.map +1 -0
  215. package/dist/jobs/contract.d.ts +193 -0
  216. package/dist/jobs/contract.d.ts.map +1 -0
  217. package/dist/jobs/contract.js +2 -0
  218. package/dist/jobs/contract.js.map +1 -0
  219. package/dist/jobs/error-text.d.ts +23 -0
  220. package/dist/jobs/error-text.d.ts.map +1 -0
  221. package/dist/jobs/error-text.js +110 -0
  222. package/dist/jobs/error-text.js.map +1 -0
  223. package/dist/jobs/handlers.d.ts.map +1 -1
  224. package/dist/jobs/handlers.js +48 -7
  225. package/dist/jobs/handlers.js.map +1 -1
  226. package/dist/jobs/memory-store.d.ts +26 -2
  227. package/dist/jobs/memory-store.d.ts.map +1 -1
  228. package/dist/jobs/memory-store.js +157 -3
  229. package/dist/jobs/memory-store.js.map +1 -1
  230. package/dist/jobs/outcomes.d.ts +46 -0
  231. package/dist/jobs/outcomes.d.ts.map +1 -0
  232. package/dist/jobs/outcomes.js +251 -0
  233. package/dist/jobs/outcomes.js.map +1 -0
  234. package/dist/jobs/prisma-store.d.ts +14 -2
  235. package/dist/jobs/prisma-store.d.ts.map +1 -1
  236. package/dist/jobs/prisma-store.js +257 -15
  237. package/dist/jobs/prisma-store.js.map +1 -1
  238. package/dist/jobs/queue.d.ts +62 -2
  239. package/dist/jobs/queue.d.ts.map +1 -1
  240. package/dist/jobs/queue.js +412 -36
  241. package/dist/jobs/queue.js.map +1 -1
  242. package/dist/jobs/retention.d.ts +11 -0
  243. package/dist/jobs/retention.d.ts.map +1 -0
  244. package/dist/jobs/retention.js +18 -0
  245. package/dist/jobs/retention.js.map +1 -0
  246. package/dist/jobs/review.d.ts +111 -0
  247. package/dist/jobs/review.d.ts.map +1 -0
  248. package/dist/jobs/review.js +461 -0
  249. package/dist/jobs/review.js.map +1 -0
  250. package/dist/jobs/routes.d.ts.map +1 -1
  251. package/dist/jobs/routes.js +491 -16
  252. package/dist/jobs/routes.js.map +1 -1
  253. package/dist/jobs/serialize.d.ts +40 -0
  254. package/dist/jobs/serialize.d.ts.map +1 -0
  255. package/dist/jobs/serialize.js +275 -0
  256. package/dist/jobs/serialize.js.map +1 -0
  257. package/dist/jobs/types.d.ts +141 -2
  258. package/dist/jobs/types.d.ts.map +1 -1
  259. package/dist/jobs/worker-status.d.ts +27 -0
  260. package/dist/jobs/worker-status.d.ts.map +1 -0
  261. package/dist/jobs/worker-status.js +66 -0
  262. package/dist/jobs/worker-status.js.map +1 -0
  263. package/dist/media/optimize.d.ts.map +1 -1
  264. package/dist/media/optimize.js +4 -2
  265. package/dist/media/optimize.js.map +1 -1
  266. package/dist/next-site.d.ts +1 -0
  267. package/dist/next-site.d.ts.map +1 -1
  268. package/dist/next-site.js +3 -0
  269. package/dist/next-site.js.map +1 -1
  270. package/dist/seo/audit-runner.d.ts.map +1 -1
  271. package/dist/seo/audit-runner.js +23 -2
  272. package/dist/seo/audit-runner.js.map +1 -1
  273. package/dist/seo/issue-fix-link-insert.d.ts +11 -0
  274. package/dist/seo/issue-fix-link-insert.d.ts.map +1 -1
  275. package/dist/seo/issue-fix-link-insert.js +122 -8
  276. package/dist/seo/issue-fix-link-insert.js.map +1 -1
  277. package/dist/server-site.d.ts.map +1 -1
  278. package/dist/server-site.js +15 -0
  279. package/dist/server-site.js.map +1 -1
  280. package/dist/site.d.ts +8 -0
  281. package/dist/site.d.ts.map +1 -1
  282. package/dist/site.js +6 -0
  283. package/dist/site.js.map +1 -1
  284. package/dist/webhooks/index.d.ts +3 -1
  285. package/dist/webhooks/index.d.ts.map +1 -1
  286. package/dist/webhooks/index.js.map +1 -1
  287. package/package.json +6 -1
  288. package/prisma/migrations/0025_job_cancel_review/down.sql +60 -0
  289. package/prisma/migrations/0025_job_cancel_review/migration.sql +56 -0
  290. package/prisma/migrations/0026_job_creator_system_settings/down.sql +30 -0
  291. package/prisma/migrations/0026_job_creator_system_settings/migration.sql +14 -0
  292. package/prisma/migrations/0027_chrome_regions/down.sql +24 -0
  293. package/prisma/migrations/0027_chrome_regions/migration.sql +16 -0
  294. package/prisma/schema.prisma +105 -15
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Validation for `PUT /chrome/schema`, the body `prenta push chrome` sends.
3
+ * Known options are checked and copied in a fixed order; options this version
4
+ * doesn't know are dropped, so a newer SDK can still push to an older CMS.
5
+ */
6
+ import { CHROME_REGIONS } from './schema.js';
7
+ /** Field keys and variant ids start with a letter, so JSON keeps them in the order written. */
8
+ const FIELD_KEY = /^[A-Za-z][A-Za-z0-9_]{0,39}$/;
9
+ const VARIANT_ID = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;
10
+ /**
11
+ * A key that can't be confused with an `Object.prototype` member
12
+ * (`toString`, `constructor`, …), which a plain-object lookup would find on
13
+ * every object. Lookups are own-property as well; this keeps such names out
14
+ * of the schema altogether.
15
+ */
16
+ function notReserved(key) {
17
+ return !(key in Object.prototype);
18
+ }
19
+ export function isFieldKey(key) {
20
+ return FIELD_KEY.test(key) && notReserved(key);
21
+ }
22
+ export function isVariantId(id) {
23
+ return VARIANT_ID.test(id) && notReserved(id);
24
+ }
25
+ const TOKEN = /^\{[A-Za-z][A-Za-z0-9_]{0,28}\}$/;
26
+ const MAX_FIELDS = 60;
27
+ const MAX_VARIANTS = 24;
28
+ const MAX_OPTIONS = 50;
29
+ const MAX_TEXT = 5000;
30
+ /** Upper bound for a menu list (`field.menu({ list: true, max })`). */
31
+ export const MAX_MENU_LIST = 20;
32
+ class SchemaError extends Error {
33
+ }
34
+ function fail(message) {
35
+ throw new SchemaError(message);
36
+ }
37
+ function isRecord(value) {
38
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
39
+ }
40
+ function optionalString(value, where, max) {
41
+ if (value === undefined || value === null || value === '')
42
+ return undefined;
43
+ if (typeof value !== 'string')
44
+ fail(`${where} must be a string`);
45
+ if (value.length > max)
46
+ fail(`${where} is longer than ${max} characters`);
47
+ return value;
48
+ }
49
+ function optionalBoolean(value, where) {
50
+ if (value === undefined)
51
+ return undefined;
52
+ if (typeof value !== 'boolean')
53
+ fail(`${where} must be true or false`);
54
+ return value;
55
+ }
56
+ function optionalInt(value, where, min, max) {
57
+ if (value === undefined)
58
+ return undefined;
59
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) {
60
+ fail(`${where} must be a whole number from ${min} to ${max}`);
61
+ }
62
+ return value;
63
+ }
64
+ /** Builds the field in a fixed property order and leaves out what wasn't set. */
65
+ function compact(fieldDef) {
66
+ const out = {};
67
+ for (const [key, value] of Object.entries(fieldDef))
68
+ if (value !== undefined)
69
+ out[key] = value;
70
+ return out;
71
+ }
72
+ function parseField(key, raw, region) {
73
+ const where = `${region}.${key}`;
74
+ if (!isRecord(raw))
75
+ fail(`${where} must be a field`);
76
+ const common = {
77
+ label: optionalString(raw.label, `${where}.label`, 80),
78
+ help: optionalString(raw.help, `${where}.help`, 300),
79
+ renamedFrom: optionalString(raw.renamedFrom, `${where}.renamedFrom`, 40),
80
+ };
81
+ if (common.renamedFrom !== undefined) {
82
+ if (!isFieldKey(common.renamedFrom))
83
+ fail(`${where}.renamedFrom is not a field key`);
84
+ if (common.renamedFrom === key)
85
+ fail(`${where}.renamedFrom can't be the field's own key`);
86
+ }
87
+ switch (raw.type) {
88
+ case 'brand':
89
+ if (raw.key !== 'logo' && raw.key !== 'name')
90
+ fail(`${where}.key must be "logo" or "name"`);
91
+ return compact({ type: 'brand', key: raw.key, ...common });
92
+ case 'menu':
93
+ return compact({
94
+ type: 'menu',
95
+ optional: optionalBoolean(raw.optional, `${where}.optional`),
96
+ list: optionalBoolean(raw.list, `${where}.list`),
97
+ max: optionalInt(raw.max, `${where}.max`, 1, MAX_MENU_LIST),
98
+ default: optionalString(raw.default, `${where}.default`, 200),
99
+ ...common,
100
+ });
101
+ case 'link':
102
+ return compact({
103
+ type: 'link',
104
+ optional: optionalBoolean(raw.optional, `${where}.optional`),
105
+ ...common,
106
+ });
107
+ case 'text': {
108
+ if (raw.format !== undefined && raw.format !== 'tel' && raw.format !== 'email') {
109
+ fail(`${where}.format must be "tel" or "email"`);
110
+ }
111
+ let tokens;
112
+ if (raw.tokens !== undefined) {
113
+ if (!Array.isArray(raw.tokens) || raw.tokens.length > 10) {
114
+ fail(`${where}.tokens must be a list of up to 10 tokens`);
115
+ }
116
+ tokens = raw.tokens.map((token) => {
117
+ if (typeof token !== 'string' || !TOKEN.test(token)) {
118
+ fail(`${where}.tokens must look like "{year}"`);
119
+ }
120
+ return token;
121
+ });
122
+ }
123
+ return compact({
124
+ type: 'text',
125
+ optional: optionalBoolean(raw.optional, `${where}.optional`),
126
+ format: raw.format,
127
+ tokens,
128
+ max: optionalInt(raw.max, `${where}.max`, 1, MAX_TEXT),
129
+ ...common,
130
+ });
131
+ }
132
+ case 'textarea':
133
+ return compact({
134
+ type: 'textarea',
135
+ max: optionalInt(raw.max, `${where}.max`, 1, MAX_TEXT),
136
+ ...common,
137
+ });
138
+ case 'select': {
139
+ if (!Array.isArray(raw.options) || raw.options.length === 0) {
140
+ fail(`${where}.options must list at least one option`);
141
+ }
142
+ if (raw.options.length > MAX_OPTIONS)
143
+ fail(`${where} has more than ${MAX_OPTIONS} options`);
144
+ const options = raw.options.map((option) => {
145
+ if (typeof option !== 'string' || option === '' || option.length > 60) {
146
+ fail(`${where}.options must be non-empty strings of up to 60 characters`);
147
+ }
148
+ return option;
149
+ });
150
+ if (new Set(options).size !== options.length)
151
+ fail(`${where}.options repeats an option`);
152
+ const fallback = optionalString(raw.default, `${where}.default`, 60);
153
+ if (fallback !== undefined && !options.includes(fallback)) {
154
+ fail(`${where}.default must be one of its options`);
155
+ }
156
+ return compact({ type: 'select', options, default: fallback, ...common });
157
+ }
158
+ case 'boolean':
159
+ return compact({
160
+ type: 'boolean',
161
+ default: optionalBoolean(raw.default, `${where}.default`),
162
+ ...common,
163
+ });
164
+ case 'social':
165
+ return compact({ type: 'social', ...common });
166
+ default:
167
+ return fail(`${where}.type must be one of brand, menu, link, text, textarea, select, boolean, social`);
168
+ }
169
+ }
170
+ function parseRegion(raw, index) {
171
+ if (!isRecord(raw))
172
+ fail(`regions[${index}] must be a region`);
173
+ const region = raw.region;
174
+ if (typeof region !== 'string' || !CHROME_REGIONS.includes(region)) {
175
+ fail(`regions[${index}].region must be one of: ${CHROME_REGIONS.join(', ')}`);
176
+ }
177
+ const component = raw.component;
178
+ if (typeof component !== 'string' || component.trim() === '' || component.length > 500) {
179
+ fail(`${region}.component must be the component's path`);
180
+ }
181
+ if (!isRecord(raw.variants))
182
+ fail(`${region}.variants must map variant ids to labels`);
183
+ const variantEntries = Object.entries(raw.variants);
184
+ if (variantEntries.length === 0)
185
+ fail(`${region} needs at least one variant`);
186
+ if (variantEntries.length > MAX_VARIANTS)
187
+ fail(`${region} has more than ${MAX_VARIANTS} variants`);
188
+ const variants = {};
189
+ for (const [id, label] of variantEntries) {
190
+ if (!isVariantId(id)) {
191
+ fail(`${region} variant "${id}" must start with a letter, use letters, digits, - or _, and not be a reserved name`);
192
+ }
193
+ if (typeof label !== 'string' || label.trim() === '' || label.length > 80) {
194
+ fail(`${region} variant "${id}" needs a label of up to 80 characters`);
195
+ }
196
+ variants[id] = label;
197
+ }
198
+ if (!isRecord(raw.fields))
199
+ fail(`${region}.fields must map field keys to fields`);
200
+ const fieldEntries = Object.entries(raw.fields);
201
+ if (fieldEntries.length > MAX_FIELDS)
202
+ fail(`${region} has more than ${MAX_FIELDS} fields`);
203
+ const fields = {};
204
+ for (const [key, value] of fieldEntries) {
205
+ if (!isFieldKey(key)) {
206
+ fail(`${region} field "${key}" must start with a letter, use letters, digits or _, and not be a reserved name`);
207
+ }
208
+ fields[key] = parseField(key, value, region);
209
+ }
210
+ const renamedFrom = new Set();
211
+ for (const [key, def] of Object.entries(fields)) {
212
+ if (!def.renamedFrom)
213
+ continue;
214
+ if (def.renamedFrom in fields) {
215
+ fail(`${region}.${key}.renamedFrom names "${def.renamedFrom}", which is still a field`);
216
+ }
217
+ if (renamedFrom.has(def.renamedFrom)) {
218
+ fail(`${region}: two fields are renamed from "${def.renamedFrom}"`);
219
+ }
220
+ renamedFrom.add(def.renamedFrom);
221
+ }
222
+ return { region: region, component, variants, fields };
223
+ }
224
+ function sourceString(value, where) {
225
+ if (value === undefined || value === null)
226
+ return '';
227
+ if (typeof value !== 'string' || value.length > 200) {
228
+ fail(`source.${where} must be a string of up to 200 characters`);
229
+ }
230
+ return value.trim();
231
+ }
232
+ /**
233
+ * Every signed-in user can read the source, so a repo given as a remote URL
234
+ * with credentials (`https://oauth2:TOKEN@host/site`) keeps only what follows
235
+ * the last `@`. `prenta push chrome` strips them too; this covers other callers.
236
+ */
237
+ function withoutCredentials(repo) {
238
+ const at = repo.lastIndexOf('@');
239
+ if (at === -1)
240
+ return repo;
241
+ const scheme = repo.match(/^[a-z][a-z0-9+.-]*:\/\//i)?.[0] ?? '';
242
+ return scheme + repo.slice(at + 1);
243
+ }
244
+ /** Validate a schema push. Every region the site defines must be in it; a region left out loses its schema. */
245
+ export function parseSchemaRead(body) {
246
+ try {
247
+ if (!isRecord(body))
248
+ fail('Send { regions, source }');
249
+ if (!Array.isArray(body.regions))
250
+ fail('regions must be a list');
251
+ if (body.regions.length > CHROME_REGIONS.length) {
252
+ fail(`regions can hold at most ${CHROME_REGIONS.length} regions`);
253
+ }
254
+ const regions = body.regions.map(parseRegion);
255
+ const names = regions.map((region) => region.region);
256
+ if (new Set(names).size !== names.length)
257
+ fail('Each region can only be sent once');
258
+ const source = isRecord(body.source) ? body.source : {};
259
+ return {
260
+ ok: true,
261
+ value: {
262
+ regions,
263
+ source: {
264
+ repo: withoutCredentials(sourceString(source.repo, 'repo')),
265
+ branch: sourceString(source.branch, 'branch'),
266
+ commit: sourceString(source.commit, 'commit'),
267
+ },
268
+ },
269
+ };
270
+ }
271
+ catch (err) {
272
+ if (err instanceof SchemaError)
273
+ return { ok: false, error: err.message };
274
+ throw err;
275
+ }
276
+ }
277
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/chrome/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { PrentaDB } from '../db/client-types.js';
2
+ import { type ChromeRow, type ChromeRowPatch, type ChromeStore, type ChromeWriteOptions } from './store.js';
3
+ export declare class PrismaChromeStore implements ChromeStore {
4
+ private readonly db;
5
+ constructor(db: PrentaDB);
6
+ get(region: string): Promise<ChromeRow | null>;
7
+ list(): Promise<ChromeRow[]>;
8
+ ensure(region: string, now: Date): Promise<void>;
9
+ update(row: ChromeRow, patch: ChromeRowPatch, now: Date, options?: ChromeWriteOptions): Promise<ChromeRow | null>;
10
+ }
11
+ //# sourceMappingURL=prisma-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-store.d.ts","sourceRoot":"","sources":["../../src/chrome/prisma-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAErD,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAA;AAkCnB,qBAAa,iBAAkB,YAAW,WAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAEnC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAK9C,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAK5B,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,MAAM,CACV,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,IAAI,EACT,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;CAS7B"}
@@ -0,0 +1,48 @@
1
+ import { patchedRow, writtenAt, } from './store.js';
2
+ function toRow(raw) {
3
+ const values = raw.values;
4
+ return {
5
+ region: raw.region,
6
+ schema: raw.schema ?? null,
7
+ schemaHash: raw.schemaHash ?? null,
8
+ variant: raw.variant ?? null,
9
+ values: typeof values === 'object' && values !== null && !Array.isArray(values)
10
+ ? values
11
+ : {},
12
+ orphans: Array.isArray(raw.orphans) ? raw.orphans : [],
13
+ state: raw.state ?? null,
14
+ version: typeof raw.version === 'number' ? raw.version : 0,
15
+ updatedById: raw.updatedById ?? null,
16
+ updatedAt: raw.updatedAt ? new Date(raw.updatedAt) : null,
17
+ };
18
+ }
19
+ export class PrismaChromeStore {
20
+ db;
21
+ constructor(db) {
22
+ this.db = db;
23
+ }
24
+ async get(region) {
25
+ const row = await this.db.chromeRegion.findUnique({ where: { region } });
26
+ return row ? toRow(row) : null;
27
+ }
28
+ async list() {
29
+ const rows = await this.db.chromeRegion.findMany({ orderBy: { region: 'asc' } });
30
+ return rows.map(toRow);
31
+ }
32
+ async ensure(region, now) {
33
+ await this.db.chromeRegion.createMany({
34
+ data: [{ region, values: {}, orphans: [], version: 0, updatedAt: now }],
35
+ skipDuplicates: true,
36
+ });
37
+ }
38
+ async update(row, patch, now, options) {
39
+ const { count } = await this.db.chromeRegion.updateMany({
40
+ where: { region: row.region, version: row.version },
41
+ // A JS null clears a nullable Json column on Prisma 7.
42
+ // `updatedAt` is always sent, so Prisma's @updatedAt doesn't move it on a `touch: false` write.
43
+ data: { ...patch, version: row.version + 1, updatedAt: writtenAt(row, now, options) },
44
+ });
45
+ return count === 1 ? patchedRow(row, patch, now, options) : null;
46
+ }
47
+ }
48
+ //# sourceMappingURL=prisma-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-store.js","sourceRoot":"","sources":["../../src/chrome/prisma-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { PrentaCMSConfig } from '../config/types.js';
2
+ import type { PrentaDB } from '../db/client-types.js';
3
+ import type { PublicChrome } from './contract.js';
4
+ import { type ChromeStore } from './store.js';
5
+ /** `/x/y/` → `/x/y`. Null for anything that isn't a site path. */
6
+ export declare function normalizeChromePath(value: string | null | undefined): string | null;
7
+ /**
8
+ * Cache tags for `/public/chrome?path=`: the shared chrome set, plus the
9
+ * collection of every page whose override it reads. An ancestor can live in
10
+ * another collection than the page (`/blog` in pages, `/blog/hello` in posts).
11
+ */
12
+ export declare function chromeReadTags(config: Pick<PrentaCMSConfig, 'collections'> | null, path: string): string[];
13
+ export interface LoadPublicChromeOptions {
14
+ db: PrentaDB;
15
+ store: ChromeStore;
16
+ config: Pick<PrentaCMSConfig, 'collections'> | null;
17
+ path: string;
18
+ now: Date;
19
+ }
20
+ /** Everything the site gets for one path. */
21
+ export declare function loadPublicChrome(options: LoadPublicChromeOptions): Promise<PublicChrome>;
22
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/chrome/public.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAIrD,OAAO,KAAK,EAEV,YAAY,EAGb,MAAM,eAAe,CAAA;AAUtB,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAG/D,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAMnF;AAyCD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,EACnD,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAKV;AA6FD,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,QAAQ,CAAA;IACZ,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,IAAI,CAAA;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,IAAI,CAAA;CACV;AAED,6CAA6C;AAC7C,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqD9F"}
@@ -0,0 +1,181 @@
1
+ import { chromeCacheTags, chromePagePaths } from '../cache/http.js';
2
+ import { matchPathToCollection } from '../seo/resolve-path.js';
3
+ import { coercePublicNavItems } from '../site.js';
4
+ import { readAnnouncement, toPublicAnnouncement } from './announcement.js';
5
+ import { effectiveRegion, menuSlugs, publicRegion, readRegionOverride, withEtag, } from './resolve.js';
6
+ import { CHROME_REGIONS } from './schema.js';
7
+ import { ANNOUNCEMENT_ROW } from './store.js';
8
+ import { fromStoredSchema, isRecord } from './values.js';
9
+ /** `/x/y/` → `/x/y`. Null for anything that isn't a site path. */
10
+ export function normalizeChromePath(value) {
11
+ if (typeof value !== 'string')
12
+ return null;
13
+ const trimmed = value.trim();
14
+ if (!trimmed.startsWith('/') || trimmed.startsWith('//') || trimmed.length > 2048)
15
+ return null;
16
+ if (/[\s?#]/.test(trimmed))
17
+ return null;
18
+ return trimmed.replace(/\/+$/, '') || '/';
19
+ }
20
+ function overridesOf(data) {
21
+ const layout = isRecord(data) && isRecord(data._layout) ? data._layout : {};
22
+ const out = {};
23
+ for (const region of CHROME_REGIONS) {
24
+ const override = readRegionOverride(layout[region]);
25
+ if (override !== undefined)
26
+ out[region] = override;
27
+ }
28
+ return out;
29
+ }
30
+ function pageRef(config, path) {
31
+ const match = matchPathToCollection(config, path);
32
+ if (!match)
33
+ return null;
34
+ return { collection: match.collection, slugs: match.isRoot ? ['home', 'index'] : [match.slug] };
35
+ }
36
+ /** The page first, then its ancestors nearest first, so the first override found wins. */
37
+ function pageRefs(config, path) {
38
+ const refs = [];
39
+ for (const [index, pagePath] of chromePagePaths(path).entries()) {
40
+ const ref = pageRef(config, pagePath);
41
+ if (ref)
42
+ refs.push({ ref, isPage: index === 0 });
43
+ }
44
+ return refs;
45
+ }
46
+ /**
47
+ * Cache tags for `/public/chrome?path=`: the shared chrome set, plus the
48
+ * collection of every page whose override it reads. An ancestor can live in
49
+ * another collection than the page (`/blog` in pages, `/blog/hello` in posts).
50
+ */
51
+ export function chromeReadTags(config, path) {
52
+ return chromeCacheTags(path, pageRefs(config, path).map(({ ref }) => ref.collection));
53
+ }
54
+ /**
55
+ * The page's own overrides and, per region, the nearest ancestor's. The root
56
+ * page is nobody's ancestor: the site default covers every page already.
57
+ */
58
+ async function loadPageOverrides(db, config, path) {
59
+ const refs = pageRefs(config, path);
60
+ if (refs.length === 0)
61
+ return { page: {}, ancestor: {} };
62
+ const docs = (await db.document.findMany({
63
+ where: {
64
+ deletedAt: null,
65
+ status: 'PUBLISHED',
66
+ OR: refs.map(({ ref }) => ({
67
+ collection: ref.collection,
68
+ OR: [
69
+ { slug: { in: ref.slugs } },
70
+ ...ref.slugs.map((slug) => ({ data: { path: ['slug'], equals: slug } })),
71
+ ],
72
+ })),
73
+ },
74
+ select: { collection: true, slug: true, data: true },
75
+ }));
76
+ const find = (ref) => docs.find((doc) => doc.collection === ref.collection && ref.slugs.includes(doc.slug ?? '')) ??
77
+ docs.find((doc) => doc.collection === ref.collection &&
78
+ isRecord(doc.data) &&
79
+ typeof doc.data.slug === 'string' &&
80
+ ref.slugs.includes(doc.data.slug));
81
+ let page = {};
82
+ const ancestor = {};
83
+ for (const { ref, isPage } of refs) {
84
+ const doc = find(ref);
85
+ if (!doc)
86
+ continue;
87
+ const overrides = overridesOf(doc.data);
88
+ if (isPage) {
89
+ page = overrides;
90
+ continue;
91
+ }
92
+ for (const region of CHROME_REGIONS) {
93
+ if (ancestor[region] === undefined && overrides[region] !== undefined) {
94
+ ancestor[region] = overrides[region];
95
+ }
96
+ }
97
+ }
98
+ return { page, ancestor };
99
+ }
100
+ /** Menus by slug, with the rules `/public/navigations/:slug` uses: any status but ARCHIVED. */
101
+ async function loadMenus(db, slugs) {
102
+ const menus = new Map();
103
+ if (slugs.length === 0)
104
+ return menus;
105
+ const docs = (await db.document.findMany({
106
+ where: {
107
+ collection: 'navigations',
108
+ deletedAt: null,
109
+ status: { not: 'ARCHIVED' },
110
+ OR: [
111
+ { slug: { in: slugs } },
112
+ ...slugs.map((slug) => ({ data: { path: ['slug'], equals: slug } })),
113
+ ],
114
+ },
115
+ orderBy: { updatedAt: 'desc' },
116
+ }));
117
+ for (const doc of docs) {
118
+ const data = isRecord(doc.data) ? doc.data : {};
119
+ const slug = typeof data.slug === 'string' && data.slug ? data.slug : doc.slug;
120
+ if (!slug || !slugs.includes(slug) || menus.has(slug))
121
+ continue;
122
+ menus.set(slug, {
123
+ id: slug,
124
+ name: typeof data.name === 'string' ? data.name : (doc.title ?? ''),
125
+ items: coercePublicNavItems(data.items),
126
+ });
127
+ }
128
+ return menus;
129
+ }
130
+ async function loadBrand(db) {
131
+ const { resolveBrand } = await import('../appearance/index.js');
132
+ const brand = await resolveBrand(db, null);
133
+ return { logo: brand.public.primary, name: brand.siteTitle ?? '' };
134
+ }
135
+ /** Everything the site gets for one path. */
136
+ export async function loadPublicChrome(options) {
137
+ const { db, store, config, path, now } = options;
138
+ const rows = await store.list();
139
+ const byRegion = new Map(rows.map((row) => [row.region, row]));
140
+ const schemas = new Map();
141
+ for (const region of CHROME_REGIONS) {
142
+ const schema = fromStoredSchema(region, byRegion.get(region)?.schema);
143
+ if (schema)
144
+ schemas.set(region, schema);
145
+ }
146
+ const resolved = new Map();
147
+ if (schemas.size > 0) {
148
+ const { page, ancestor } = await loadPageOverrides(db, config, path);
149
+ for (const [region, schema] of schemas) {
150
+ const row = byRegion.get(region);
151
+ resolved.set(region, effectiveRegion(schema, { variant: row?.variant ?? null, values: row?.values ?? {} }, [
152
+ ancestor[region],
153
+ page[region],
154
+ ]));
155
+ }
156
+ }
157
+ const slugs = new Set();
158
+ let needsBrand = false;
159
+ for (const [region, effective] of resolved) {
160
+ if (!effective)
161
+ continue;
162
+ const schema = schemas.get(region);
163
+ for (const slug of menuSlugs(schema, effective.values))
164
+ slugs.add(slug);
165
+ if (Object.values(schema.fields).some((def) => def.type === 'brand'))
166
+ needsBrand = true;
167
+ }
168
+ const [menus, brand] = await Promise.all([
169
+ loadMenus(db, [...slugs]),
170
+ needsBrand ? loadBrand(db) : Promise.resolve({ logo: null, name: '' }),
171
+ ]);
172
+ const body = { announcement: null };
173
+ for (const [region, effective] of resolved) {
174
+ body[region] = effective
175
+ ? publicRegion(schemas.get(region), effective, { menus, brand, now })
176
+ : null;
177
+ }
178
+ body.announcement = toPublicAnnouncement(readAnnouncement(byRegion.get(ANNOUNCEMENT_ROW)?.values), now);
179
+ return withEtag(body);
180
+ }
181
+ //# sourceMappingURL=public.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../src/chrome/public.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { ResolvedLogo } from '../appearance/types.js';
2
+ import type { ChromeRegionOverride, PublicAnnouncement, PublicChrome, PublicChromeRegion, RegionSchema } from './contract.js';
3
+ import type { ChromeMenu } from './schema.js';
4
+ /** A region's variant and stored-format values after overrides. */
5
+ export interface EffectiveRegion {
6
+ variant: string;
7
+ values: Record<string, unknown>;
8
+ }
9
+ /** Read one region's override from a page's `_layout`. Strings are legacy variant-document ids, not overrides. */
10
+ export declare function readRegionOverride(value: unknown): ChromeRegionOverride | null | undefined;
11
+ /**
12
+ * Apply the overrides in order (nearest ancestor, then the page) over the
13
+ * site default. `undefined` means "no override at this level".
14
+ */
15
+ export declare function effectiveRegion(schema: Pick<RegionSchema, 'variants' | 'fields'>, site: {
16
+ variant: string | null;
17
+ values: Record<string, unknown>;
18
+ }, overrides: Array<ChromeRegionOverride | null | undefined>): EffectiveRegion | null;
19
+ /** The menu slugs a region's values point at, defaults included. */
20
+ export declare function menuSlugs(schema: Pick<RegionSchema, 'fields'>, values: Record<string, unknown>): string[];
21
+ export interface PublicFieldContext {
22
+ menus: ReadonlyMap<string, ChromeMenu>;
23
+ brand: {
24
+ logo: ResolvedLogo | null;
25
+ name: string;
26
+ };
27
+ now: Date;
28
+ }
29
+ /** A region as the site receives it, every field filled in, in schema order. */
30
+ export declare function publicRegion(schema: Pick<RegionSchema, 'fields'>, region: EffectiveRegion, ctx: PublicFieldContext): PublicChromeRegion;
31
+ export declare function withEtag(body: {
32
+ header?: PublicChromeRegion | null;
33
+ footer?: PublicChromeRegion | null;
34
+ announcement: PublicAnnouncement | null;
35
+ }): PublicChrome;
36
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/chrome/resolve.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACb,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,aAAa,CAAA;AAUvD,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAO1F;AAqBD;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,QAAQ,CAAC,EACjD,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACjE,SAAS,EAAE,KAAK,CAAC,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAAC,GACxD,eAAe,GAAG,IAAI,CAsBxB;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CACvB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,EAAE,CAkBV;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACtC,KAAK,EAAE;QAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClD,GAAG,EAAE,IAAI,CAAA;CACV;AA2DD,gFAAgF;AAChF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EACpC,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,kBAAkB,GACtB,kBAAkB,CAMpB;AAQD,wBAAgB,QAAQ,CAAC,IAAI,EAAE;IAC7B,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAClC,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAClC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAA;CACxC,GAAG,YAAY,CAEf"}