@contentrain/mcp 2.3.1 → 3.0.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 (162) hide show
  1. package/README.md +1 -1
  2. package/dist/{annotations-D3tlsF38.mjs → annotations-C-tQVmot.mjs} +15 -1
  3. package/dist/annotations-C-tQVmot.mjs.map +1 -0
  4. package/dist/{apply-manager-SLCRLHN_.mjs → apply-manager-BybvnUVC.mjs} +28 -18
  5. package/dist/apply-manager-BybvnUVC.mjs.map +1 -0
  6. package/dist/{astro-parser-LNjEspnf.mjs → astro-parser-Cb9uuBpW.mjs} +3 -3
  7. package/dist/{astro-parser-LNjEspnf.mjs.map → astro-parser-Cb9uuBpW.mjs.map} +1 -1
  8. package/dist/{availability-sWWRz2W0.mjs → availability-Dgcmvv99.mjs} +1 -1
  9. package/dist/{availability-sWWRz2W0.mjs.map → availability-Dgcmvv99.mjs.map} +1 -1
  10. package/dist/{branch-lifecycle-BAfgSQBv.mjs → branch-lifecycle-B6PXZ2N7.mjs} +11 -61
  11. package/dist/branch-lifecycle-B6PXZ2N7.mjs.map +1 -0
  12. package/dist/{branch-lifecycle-D4W0WIs4.d.mts → branch-lifecycle-DhzHfzs3.d.mts} +1 -1
  13. package/dist/{branch-lifecycle-D4W0WIs4.d.mts.map → branch-lifecycle-DhzHfzs3.d.mts.map} +1 -1
  14. package/dist/{compiler-CNzm2Y2I.mjs → compiler-B6hNQeCC.mjs} +2 -2
  15. package/dist/{compiler-CNzm2Y2I.mjs.map → compiler-B6hNQeCC.mjs.map} +1 -1
  16. package/dist/{compiler-sfc.cjs-y0B0L3MH.mjs → compiler-sfc.cjs-8yY7b5bx.mjs} +2 -2
  17. package/dist/{compiler-sfc.cjs-y0B0L3MH.mjs.map → compiler-sfc.cjs-8yY7b5bx.mjs.map} +1 -1
  18. package/dist/{config-oxxgznz7.mjs → config-VlRKRwAS.mjs} +1 -1
  19. package/dist/{config-oxxgznz7.mjs.map → config-VlRKRwAS.mjs.map} +1 -1
  20. package/dist/{content-manager-DWo3G64y.d.mts → content-manager-Dn4tqDw1.d.mts} +10 -7
  21. package/dist/content-manager-Dn4tqDw1.d.mts.map +1 -0
  22. package/dist/{context-DjglDPvj.mjs → context-C3x6I3cE.mjs} +4 -4
  23. package/dist/{context-DjglDPvj.mjs.map → context-C3x6I3cE.mjs.map} +1 -1
  24. package/dist/core/apply-manager.d.mts +8 -0
  25. package/dist/core/apply-manager.d.mts.map +1 -1
  26. package/dist/core/apply-manager.mjs +10 -9
  27. package/dist/core/config.d.mts +1 -1
  28. package/dist/core/config.mjs +1 -1
  29. package/dist/core/content-manager.d.mts +2 -2
  30. package/dist/core/content-manager.mjs +2 -2
  31. package/dist/core/context.d.mts +1 -1
  32. package/dist/core/context.mjs +5 -5
  33. package/dist/core/contracts/index.d.mts +2 -2
  34. package/dist/core/doctor.mjs +7 -6
  35. package/dist/core/graph-builder.mjs +2 -2
  36. package/dist/core/meta-manager.d.mts +8 -9
  37. package/dist/core/meta-manager.d.mts.map +1 -1
  38. package/dist/core/meta-manager.mjs +2 -2
  39. package/dist/core/model-manager.d.mts +39 -3
  40. package/dist/core/model-manager.d.mts.map +1 -1
  41. package/dist/core/model-manager.mjs +3 -3
  42. package/dist/core/ops/index.d.mts +40 -3
  43. package/dist/core/ops/index.d.mts.map +1 -1
  44. package/dist/core/ops/index.mjs +4 -4
  45. package/dist/core/overlay-reader.d.mts +1 -1
  46. package/dist/core/overlay-reader.mjs +1 -1
  47. package/dist/core/scan-config.mjs +1 -1
  48. package/dist/core/scanner.mjs +3 -3
  49. package/dist/core/validator/index.d.mts +1 -1
  50. package/dist/core/validator/index.d.mts.map +1 -1
  51. package/dist/core/validator/index.mjs +4 -4
  52. package/dist/{detect-CdDU4Ew_.mjs → detect-B0oXbQaP.mjs} +1 -1
  53. package/dist/{detect-CdDU4Ew_.mjs.map → detect-B0oXbQaP.mjs.map} +1 -1
  54. package/dist/{doctor-BwJ_nmqS.mjs → doctor-DNPuGgcg.mjs} +28 -15
  55. package/dist/doctor-DNPuGgcg.mjs.map +1 -0
  56. package/dist/{errors-e0YdjooK.mjs → errors-CvBS12e7.mjs} +1 -1
  57. package/dist/{errors-e0YdjooK.mjs.map → errors-CvBS12e7.mjs.map} +1 -1
  58. package/dist/fs-DLbVB-Ek.mjs.map +1 -1
  59. package/dist/git/branch-lifecycle.d.mts +1 -1
  60. package/dist/git/branch-lifecycle.mjs +3 -2
  61. package/dist/git/identity.d.mts +42 -0
  62. package/dist/git/identity.d.mts.map +1 -0
  63. package/dist/git/identity.mjs +2 -0
  64. package/dist/git/transaction.d.mts +1 -1
  65. package/dist/git/transaction.d.mts.map +1 -1
  66. package/dist/git/transaction.mjs +9 -8
  67. package/dist/{graph-builder-DK4Mh8Tn.mjs → graph-builder-BEocwW13.mjs} +2 -2
  68. package/dist/{graph-builder-DK4Mh8Tn.mjs.map → graph-builder-BEocwW13.mjs.map} +1 -1
  69. package/dist/{id-DV_T9Ic8.mjs → id-BjhaIxTL.mjs} +1 -1
  70. package/dist/{id-DV_T9Ic8.mjs.map → id-BjhaIxTL.mjs.map} +1 -1
  71. package/dist/identity-D8QoGxhT.mjs +125 -0
  72. package/dist/identity-D8QoGxhT.mjs.map +1 -0
  73. package/dist/{index-w8QHThNS.d.mts → index-BWbTJlXm.d.mts} +2 -2
  74. package/dist/index.mjs +21 -20
  75. package/dist/index.mjs.map +1 -1
  76. package/dist/{local-8dJ5NIWL.mjs → local-Db5X9mjZ.mjs} +25 -13
  77. package/dist/local-Db5X9mjZ.mjs.map +1 -0
  78. package/dist/{meta-manager-CJUiTgP2.mjs → meta-manager-B_Se183X.mjs} +29 -5
  79. package/dist/meta-manager-B_Se183X.mjs.map +1 -0
  80. package/dist/{model-manager-DP2CZiMT.mjs → model-manager-DgyKMjLN.mjs} +169 -25
  81. package/dist/model-manager-DgyKMjLN.mjs.map +1 -0
  82. package/dist/{node-BxujauDw.mjs → node-DUGiIkv1.mjs} +1 -1
  83. package/dist/{node-BxujauDw.mjs.map → node-DUGiIkv1.mjs.map} +1 -1
  84. package/dist/{ops-CGKIKwDc.mjs → ops-BzbThweu.mjs} +165 -26
  85. package/dist/ops-BzbThweu.mjs.map +1 -0
  86. package/dist/{overlay-reader-DNaVsgiS.mjs → overlay-reader-CkU_pGXZ.mjs} +1 -1
  87. package/dist/{overlay-reader-DNaVsgiS.mjs.map → overlay-reader-CkU_pGXZ.mjs.map} +1 -1
  88. package/dist/{paths-enT2coeX.mjs → paths-CdPPWpbG.mjs} +1 -1
  89. package/dist/{paths-enT2coeX.mjs.map → paths-CdPPWpbG.mjs.map} +1 -1
  90. package/dist/providers/github/index.d.mts +1 -1
  91. package/dist/providers/github/index.mjs +2 -2
  92. package/dist/providers/gitlab/index.d.mts +1 -1
  93. package/dist/providers/gitlab/index.mjs +2 -2
  94. package/dist/providers/local/index.d.mts +7 -1
  95. package/dist/providers/local/index.d.mts.map +1 -1
  96. package/dist/providers/local/index.mjs +11 -10
  97. package/dist/{scan-config-BlNLRCMx.mjs → scan-config-Dx49nCqk.mjs} +1 -1
  98. package/dist/{scan-config-BlNLRCMx.mjs.map → scan-config-Dx49nCqk.mjs.map} +1 -1
  99. package/dist/{scanner-CGWhmpDz.mjs → scanner-BSvXjfkp.mjs} +6 -6
  100. package/dist/{scanner-CGWhmpDz.mjs.map → scanner-BSvXjfkp.mjs.map} +1 -1
  101. package/dist/serialization-tmgfFBOh.mjs +2 -0
  102. package/dist/server/http/index.d.mts +1 -1
  103. package/dist/server/http/index.mjs +21 -20
  104. package/dist/server/http/index.mjs.map +1 -1
  105. package/dist/{server-DLauBiu2.d.mts → server-CLPNnhYL.d.mts} +2 -2
  106. package/dist/{server-DLauBiu2.d.mts.map → server-CLPNnhYL.d.mts.map} +1 -1
  107. package/dist/{server-CUZnuHQx.mjs → server-D-zJWbdI.mjs} +313 -115
  108. package/dist/server-D-zJWbdI.mjs.map +1 -0
  109. package/dist/server.d.mts +1 -1
  110. package/dist/server.mjs +21 -20
  111. package/dist/{source-map-generator-Bvbu-kM5.mjs → source-map-generator-DhjiQdV3.mjs} +1 -1
  112. package/dist/{source-map-generator-Bvbu-kM5.mjs.map → source-map-generator-DhjiQdV3.mjs.map} +1 -1
  113. package/dist/{svelte-parser-DaFK9iY0.mjs → svelte-parser-CwySu9yn.mjs} +3 -3
  114. package/dist/{svelte-parser-DaFK9iY0.mjs.map → svelte-parser-CwySu9yn.mjs.map} +1 -1
  115. package/dist/templates/index.mjs +1 -1
  116. package/dist/{templates-D6EllixQ.mjs → templates-CAkTIRkE.mjs} +430 -109
  117. package/dist/templates-CAkTIRkE.mjs.map +1 -0
  118. package/dist/testing/memory-provider.d.mts +52 -0
  119. package/dist/testing/memory-provider.d.mts.map +1 -0
  120. package/dist/testing/memory-provider.mjs +205 -0
  121. package/dist/testing/memory-provider.mjs.map +1 -0
  122. package/dist/tools/annotations.d.mts.map +1 -1
  123. package/dist/tools/annotations.mjs +1 -1
  124. package/dist/tools/availability.mjs +1 -1
  125. package/dist/{transaction-1SPznNt3.mjs → transaction-BW9ektWu.mjs} +13 -12
  126. package/dist/transaction-BW9ektWu.mjs.map +1 -0
  127. package/dist/{tsx-parser-md1N0Niu.mjs → tsx-parser-BvsK6lyG.mjs} +1 -1
  128. package/dist/{tsx-parser-md1N0Niu.mjs.map → tsx-parser-BvsK6lyG.mjs.map} +1 -1
  129. package/dist/tsx-parser-Byc7HlJ8.mjs +2 -0
  130. package/dist/util/detect.mjs +1 -1
  131. package/dist/util/fs.d.mts +1 -1
  132. package/dist/util/fs.d.mts.map +1 -1
  133. package/dist/util/id.mjs +1 -1
  134. package/dist/{validator-ChiYk6ap.mjs → validator-0sJ9vh1j.mjs} +65 -8
  135. package/dist/validator-0sJ9vh1j.mjs.map +1 -0
  136. package/dist/{vue-parser-CHxDohd8.mjs → vue-parser-auedZiJG.mjs} +3 -3
  137. package/dist/{vue-parser-CHxDohd8.mjs.map → vue-parser-auedZiJG.mjs.map} +1 -1
  138. package/package.json +13 -5
  139. package/testing/conformance/01-new-collection-entry/expected/.contentrain/meta/blog/en.json +1 -0
  140. package/testing/conformance/01-new-collection-entry/expected/.contentrain/models/blog.json +6 -5
  141. package/testing/conformance/01-new-collection-entry/setup/.contentrain/models/blog.json +6 -5
  142. package/testing/conformance/02-new-singleton/expected/.contentrain/meta/hero/en.json +1 -0
  143. package/testing/conformance/02-new-singleton/expected/.contentrain/models/hero.json +6 -5
  144. package/testing/conformance/02-new-singleton/setup/.contentrain/models/hero.json +6 -5
  145. package/testing/conformance/03-new-dictionary/expected/.contentrain/meta/ui-strings/en.json +1 -0
  146. package/testing/conformance/03-new-dictionary/expected/.contentrain/models/ui-strings.json +4 -3
  147. package/testing/conformance/03-new-dictionary/setup/.contentrain/models/ui-strings.json +4 -3
  148. package/dist/annotations-D3tlsF38.mjs.map +0 -1
  149. package/dist/apply-manager-SLCRLHN_.mjs.map +0 -1
  150. package/dist/branch-lifecycle-BAfgSQBv.mjs.map +0 -1
  151. package/dist/content-manager-DWo3G64y.d.mts.map +0 -1
  152. package/dist/doctor-BwJ_nmqS.mjs.map +0 -1
  153. package/dist/local-8dJ5NIWL.mjs.map +0 -1
  154. package/dist/meta-manager-CJUiTgP2.mjs.map +0 -1
  155. package/dist/model-manager-DP2CZiMT.mjs.map +0 -1
  156. package/dist/ops-CGKIKwDc.mjs.map +0 -1
  157. package/dist/serialization-B1CEzR4H.mjs +0 -2
  158. package/dist/server-CUZnuHQx.mjs.map +0 -1
  159. package/dist/templates-D6EllixQ.mjs.map +0 -1
  160. package/dist/transaction-1SPznNt3.mjs.map +0 -1
  161. package/dist/tsx-parser-C3XsIrwU.mjs +0 -2
  162. package/dist/validator-ChiYk6ap.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { n as contentFilePath, r as documentFilePath, t as contentDirPath } from "./paths-CmVw5Cw2.mjs";
2
2
  import { a as readJson, c as writeText, i as readDir, n as ensureDir, o as readText, s as writeJson, t as contentrainDir } from "./fs-DLbVB-Ek.mjs";
3
- import { i as writeMeta, n as mergeEntryMeta, r as readMeta, t as deleteMeta } from "./meta-manager-CJUiTgP2.mjs";
3
+ import { a as writeMeta, i as readMeta, n as deleteMeta, r as mergeEntryMeta } from "./meta-manager-B_Se183X.mjs";
4
4
  import { join, resolve } from "node:path";
5
- import { generateEntryId, parseMarkdownFrontmatter, parseMarkdownFrontmatter as parseFrontmatter, serializeMarkdownFrontmatter, serializeMarkdownFrontmatter as serializeFrontmatter, validateEntryId as validateEntryId$1, validateLocale as validateLocale$1, validateSlug as validateSlug$1 } from "@contentrain/types";
5
+ import { DICTIONARY_TITLE_FIELD, LOCALE_PATTERN, MODEL_FIELD_ORDER, MODEL_FIELD_ORDER as MODEL_FIELD_ORDER$1, TITLE_FIELD_TYPES, generateEntryId, isTitleFieldType, parseMarkdownFrontmatter, parseMarkdownFrontmatter as parseFrontmatter, serializeMarkdownFrontmatter, serializeMarkdownFrontmatter as serializeFrontmatter, validateEntryId as validateEntryId$1, validateLocale as validateLocale$1, validateSlug as validateSlug$1 } from "@contentrain/types";
6
6
  import { access, readFile, readdir, rm } from "node:fs/promises";
7
7
  import { z } from "zod";
8
8
  //#region src/providers/local/reader.ts
@@ -42,6 +42,8 @@ var LocalReader = class {
42
42
  };
43
43
  //#endregion
44
44
  //#region src/core/content-manager.ts
45
+ /** Keys named individually in a replacement advisory before it collapses to a count. */
46
+ const MAX_REPORTED_KEYS = 5;
45
47
  function resolveContentDir(projectRoot, model) {
46
48
  if (model.content_path) return join(projectRoot, model.content_path);
47
49
  return join(contentrainDir(projectRoot), "content", model.domain, model.id);
@@ -132,13 +134,19 @@ async function writeContent(projectRoot, model, entries, config, vocabulary) {
132
134
  if (!slug) throw new Error("Document entries require a slug");
133
135
  const slugErr = validateSlug$1(slug);
134
136
  if (slugErr) throw new Error(slugErr);
135
- const bodyContent = entry.data["body"] ?? "";
136
- const fmData = { ...entry.data };
137
- delete fmData["body"];
138
- if (!fmData["slug"]) fmData["slug"] = slug;
137
+ const incomingFm = { ...entry.data };
138
+ const bodySent = "body" in incomingFm;
139
+ const incomingBody = incomingFm["body"] ?? "";
140
+ delete incomingFm["body"];
141
+ if (!incomingFm["slug"]) incomingFm["slug"] = slug;
139
142
  const docPath = resolveMdFilePath(resolveContentDir(projectRoot, model), model, locale, slug);
140
- const action = await readText(docPath) ? "updated" : "created";
141
- await writeText(docPath, serializeMarkdownFrontmatter(fmData, bodyContent));
143
+ const existingRaw = await readText(docPath);
144
+ const action = existingRaw ? "updated" : "created";
145
+ const existingDoc = existingRaw ? parseMarkdownFrontmatter(existingRaw) : null;
146
+ await writeText(docPath, serializeMarkdownFrontmatter({
147
+ ...existingDoc?.frontmatter,
148
+ ...incomingFm
149
+ }, bodySent ? incomingBody : existingDoc?.body ?? ""));
142
150
  const prevMeta = await readMeta(projectRoot, model, {
143
151
  locale,
144
152
  slug,
@@ -159,10 +167,15 @@ async function writeContent(projectRoot, model, entries, config, vocabulary) {
159
167
  case "dictionary": {
160
168
  const filePath = resolveJsonFilePath(resolveContentDir(projectRoot, model), model, locale);
161
169
  const existing = await readJson(filePath) ?? {};
162
- const collisions = [];
163
- for (const key of Object.keys(entry.data)) if (key in existing && existing[key] !== entry.data[key]) collisions.push(key);
164
- if (collisions.length > 0) throw new Error(`Dictionary "${model.id}" (${locale}): ${collisions.length} key collision(s) — [${collisions.join(", ")}] already exist with different values. Read existing keys with contentrain_content_list first, or include all keys in a single save call.`);
165
170
  const advisories = [];
171
+ const incoming = entry.data;
172
+ const replaced = Object.keys(incoming).filter((k) => k in existing && existing[k] !== incoming[k]);
173
+ if (replaced.length > 0) {
174
+ const shown = replaced.slice(0, MAX_REPORTED_KEYS);
175
+ const detail = shown.map((k) => `"${k}": "${existing[k]}" → "${incoming[k]}"`).join(", ");
176
+ const more = replaced.length > shown.length ? `, and ${replaced.length - shown.length} more` : "";
177
+ advisories.push(`Dictionary "${model.id}" (${locale}): replaced ${replaced.length} existing value(s) — ${detail}${more}.`);
178
+ }
166
179
  const reverseMap = /* @__PURE__ */ new Map();
167
180
  for (const [k, v] of Object.entries(existing)) reverseMap.set(v, k);
168
181
  for (const [newKey, newValue] of Object.entries(entry.data)) {
@@ -926,17 +939,6 @@ async function countEntries(input, model) {
926
939
  }
927
940
  }
928
941
  }
929
- const MODEL_FIELD_ORDER = [
930
- "id",
931
- "name",
932
- "kind",
933
- "domain",
934
- "i18n",
935
- "description",
936
- "content_path",
937
- "locale_strategy",
938
- "fields"
939
- ];
940
942
  async function writeModel(projectRoot, model) {
941
943
  await writeJson(join(contentrainDir(projectRoot), "models", `${model.id}.json`), model, MODEL_FIELD_ORDER);
942
944
  await ensureDir(resolveContentDir(projectRoot, model));
@@ -1036,7 +1038,9 @@ const fieldDefZodSchema = z.record(z.string(), z.object({
1036
1038
  fields: z.lazy(() => z.record(z.string(), z.unknown())).optional(),
1037
1039
  accept: z.string().optional(),
1038
1040
  maxSize: z.number().optional(),
1039
- description: z.string().optional()
1041
+ description: z.string().optional(),
1042
+ label: z.union([z.string(), z.record(z.string(), z.string())]).optional().describe("Editor label. A string is one label for all locales; an object keyed by locale carries a translation each."),
1043
+ order: z.number().optional().describe("Display position, ascending. Fields without one sort last, alphabetically. Fractional values allowed.")
1040
1044
  }).strict().refine((f) => {
1041
1045
  if ((f.type === "relation" || f.type === "relations") && !f.model) return false;
1042
1046
  if (f.type === "select" && (!f.options || f.options.length === 0)) return false;
@@ -1074,8 +1078,20 @@ function checkFieldDef(raw, path, modelKind, errors, warnings, depth) {
1074
1078
  errors.push(`Field "${path}": invalid type "${type}"`);
1075
1079
  return;
1076
1080
  }
1081
+ if (def.label !== void 0) if (typeof def.label === "string") {
1082
+ if (def.label.trim() === "") errors.push(`Field "${path}": "label" is empty`);
1083
+ } else if (typeof def.label === "object" && def.label !== null && !Array.isArray(def.label)) {
1084
+ const entries = Object.entries(def.label);
1085
+ if (entries.length === 0) errors.push(`Field "${path}": "label" has no translations`);
1086
+ for (const [locale, value] of entries) {
1087
+ if (!LOCALE_PATTERN.test(locale)) errors.push(`Field "${path}": "label" key "${locale}" is not a locale code. A per-locale label nests as { "en": "…", "tr": "…" }.`);
1088
+ if (typeof value !== "string" || value.trim() === "") errors.push(`Field "${path}": "label" for "${locale}" must be a non-empty string`);
1089
+ }
1090
+ } else errors.push(`Field "${path}": "label" must be a string, or an object keyed by locale`);
1091
+ if (def.order !== void 0 && (typeof def.order !== "number" || !Number.isFinite(def.order))) errors.push(`Field "${path}": "order" must be a finite number`);
1077
1092
  if ((type === "relation" || type === "relations") && !def.model) errors.push(`Field "${path}": ${type} type requires "model" property`);
1078
1093
  if (type === "select" && (!Array.isArray(def.options) || def.options.length === 0)) errors.push(`Field "${path}": select type requires non-empty "options" array`);
1094
+ if (type === "object" && (!def.fields || typeof def.fields !== "object" || Object.keys(def.fields).length === 0)) warnings.push(`Field "${path}": "object" with no "fields" — nothing validates it and no editor can render it. Declare its shape, or use a plain type.`);
1079
1095
  if (def.options !== void 0 && type !== "select") errors.push(`Field "${path}": "options" only applies to select fields — it is ignored on "${type}"`);
1080
1096
  if (def.items !== void 0 && type !== "array") errors.push(`Field "${path}": "items" only applies to array fields — it is ignored on "${type}"`);
1081
1097
  if (def.fields !== void 0 && type !== "object") errors.push(`Field "${path}": "fields" only applies to object fields — it is ignored on "${type}"`);
@@ -1121,6 +1137,131 @@ function checkDefaultCoherence(def, type, path, errors) {
1121
1137
  else if (wantsBoolean && typeof value !== "boolean") errors.push(`Field "${path}": default must be a boolean for type "${type}"`);
1122
1138
  else if (wantsArray && !Array.isArray(value)) errors.push(`Field "${path}": default must be an array for type "${type}"`);
1123
1139
  }
1140
+ /** Field names that announce themselves as a title, most explicit first. */
1141
+ const TITLE_NAME_HINTS = [
1142
+ "title",
1143
+ "name",
1144
+ "label",
1145
+ "heading"
1146
+ ];
1147
+ /**
1148
+ * Preference among displayable types, short scalars first. A title is a label,
1149
+ * not a body: given both `question: string` and `answer: text`, the string wins.
1150
+ * Without this, "first required text field" resolves alphabetically and a FAQ
1151
+ * model gets titled by its answers.
1152
+ */
1153
+ const TITLE_TYPE_PRIORITY = [
1154
+ "string",
1155
+ "slug",
1156
+ "email",
1157
+ "url",
1158
+ "code",
1159
+ "text",
1160
+ "markdown",
1161
+ "richtext"
1162
+ ];
1163
+ /** Fields that could carry a title at all. Everything else is out of the running. */
1164
+ function titleCandidates(fields) {
1165
+ if (!fields) return [];
1166
+ const out = [];
1167
+ for (const [field, raw] of Object.entries(fields)) {
1168
+ const def = raw;
1169
+ const type = def?.type;
1170
+ if (typeof type !== "string" || !isTitleFieldType(type)) continue;
1171
+ out.push({
1172
+ field,
1173
+ type,
1174
+ required: def?.required === true
1175
+ });
1176
+ }
1177
+ return out;
1178
+ }
1179
+ function byTypeThenName(a, b) {
1180
+ const byType = TITLE_TYPE_PRIORITY.indexOf(a.type) - TITLE_TYPE_PRIORITY.indexOf(b.type);
1181
+ return byType !== 0 ? byType : a.field.localeCompare(b.field, "en");
1182
+ }
1183
+ /**
1184
+ * How strongly a field name reads as a title. Exact matches outrank snake_case
1185
+ * token matches, so `name` beats `brand_name`, and `filename` matches nothing —
1186
+ * it tokenizes to `["filename"]`, not `["file", "name"]`.
1187
+ */
1188
+ function titleNameRank(field) {
1189
+ const exact = TITLE_NAME_HINTS.indexOf(field);
1190
+ if (exact !== -1) return exact;
1191
+ const tokens = field.split("_");
1192
+ const token = TITLE_NAME_HINTS.findIndex((hint) => tokens.includes(hint));
1193
+ return token === -1 ? Number.POSITIVE_INFINITY : TITLE_NAME_HINTS.length + token;
1194
+ }
1195
+ /**
1196
+ * Pick the field a model should title its entries by.
1197
+ *
1198
+ * Migration aid only — it exists to backfill models authored before `title_field`
1199
+ * was required, and `contentrain validate --fix` is its one caller. New models
1200
+ * declare the field; nothing here runs on the write path.
1201
+ *
1202
+ * Every rung filters by `isTitleFieldType` first. That filter is the whole point:
1203
+ * an unfiltered name match hands the title to a field called `name` that happens
1204
+ * to be typed `icon`, which is the exact bug this contract replaces.
1205
+ *
1206
+ * Returns `null` when no field can render as a title. That is a real answer, not a
1207
+ * failure — guessing `image` or `relation` here would re-create the bug, so the
1208
+ * validation error stands and a human picks.
1209
+ */
1210
+ function inferTitleField(kind, fields) {
1211
+ if (kind === "dictionary") return {
1212
+ field: DICTIONARY_TITLE_FIELD,
1213
+ rule: "dictionary"
1214
+ };
1215
+ const candidates = titleCandidates(fields);
1216
+ if (candidates.length === 0) return null;
1217
+ const named = candidates.filter((c) => Number.isFinite(titleNameRank(c.field)));
1218
+ if (named.length > 0) return {
1219
+ field: named.toSorted((a, b) => {
1220
+ const byName = titleNameRank(a.field) - titleNameRank(b.field);
1221
+ return byName !== 0 ? byName : byTypeThenName(a, b);
1222
+ })[0].field,
1223
+ rule: "name-match"
1224
+ };
1225
+ const required = candidates.filter((c) => c.required);
1226
+ if (required.length > 0) return {
1227
+ field: required.toSorted(byTypeThenName)[0].field,
1228
+ rule: "required-displayable"
1229
+ };
1230
+ return {
1231
+ field: candidates.toSorted(byTypeThenName)[0].field,
1232
+ rule: "displayable"
1233
+ };
1234
+ }
1235
+ /**
1236
+ * The `title_field` rule table.
1237
+ *
1238
+ * Extracted so `validateModelDefinition` (write path) and the project validator
1239
+ * (read path) report the same wording from one place, rather than one of them
1240
+ * sniffing the other's strings.
1241
+ *
1242
+ * Chained so a model gets one title_field error, not a cascade of five.
1243
+ */
1244
+ function titleFieldIssues(input) {
1245
+ const errors = [];
1246
+ const warnings = [];
1247
+ const titleField = input.title_field;
1248
+ if (titleField === void 0 || titleField === null || titleField === "") errors.push("Missing \"title_field\". Every model must name the field shown as its title. Dictionary models use \"key\".");
1249
+ else if (typeof titleField !== "string") errors.push(`Invalid "title_field": must be a string, got ${typeof titleField}.`);
1250
+ else if (input.kind === "dictionary") {
1251
+ if (titleField !== DICTIONARY_TITLE_FIELD) errors.push(`Dictionary models must use title_field: "${DICTIONARY_TITLE_FIELD}". Dictionaries have no fields — the key is the title. Got "${titleField}".`);
1252
+ } else if (!input.fields || Object.keys(input.fields).length === 0) errors.push(`Invalid "title_field": "${titleField}" cannot resolve — the model declares no fields.`);
1253
+ else if (!(titleField in input.fields)) errors.push(`Invalid "title_field": field "${titleField}" is not defined in fields.` + (titleField === DICTIONARY_TITLE_FIELD ? ` "${DICTIONARY_TITLE_FIELD}" is reserved for dictionary models.` : ""));
1254
+ else {
1255
+ const def = input.fields[titleField];
1256
+ const type = def?.type;
1257
+ if (typeof type === "string" && !isTitleFieldType(type)) errors.push(`Invalid "title_field": field "${titleField}" has type "${type}" — a title must be one of: ${TITLE_FIELD_TYPES.join(", ")}.`);
1258
+ else if (def?.required !== true) warnings.push(`"title_field" points at optional field "${titleField}" — entries may render with an empty title. Consider required: true.`);
1259
+ }
1260
+ return {
1261
+ errors,
1262
+ warnings
1263
+ };
1264
+ }
1124
1265
  /**
1125
1266
  * Validate a model definition before writing.
1126
1267
  * Used by both the model_save tool and normalize extract.
@@ -1130,6 +1271,9 @@ function validateModelDefinition(input) {
1130
1271
  const warnings = [];
1131
1272
  if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(input.id)) errors.push(`Invalid model ID "${input.id}": must be kebab-case`);
1132
1273
  if (input.kind === "dictionary" && input.fields && Object.keys(input.fields).length > 0) errors.push("Dictionary models cannot have fields. Dictionaries store flat key-value pairs.");
1274
+ const titleIssues = titleFieldIssues(input);
1275
+ errors.push(...titleIssues.errors);
1276
+ warnings.push(...titleIssues.warnings);
1133
1277
  if (input.fields) for (const [fieldName, fieldDef] of Object.entries(input.fields)) {
1134
1278
  if (!/^[a-z][a-z0-9_]*$/.test(fieldName)) errors.push(`Field "${fieldName}": invalid name — must be snake_case starting with letter`);
1135
1279
  checkFieldDef(fieldDef, fieldName, input.kind, errors, warnings, 0);
@@ -1140,6 +1284,6 @@ function validateModelDefinition(input) {
1140
1284
  };
1141
1285
  }
1142
1286
  //#endregion
1143
- export { LocalReader as C, writeContent as S, resolveMdFilePath as _, fieldDefZodSchema as a, validateLocale$1 as b, validateModelDefinition as c, listContent as d, parseFrontmatter as f, resolveLocaleStrategy as g, resolveJsonFilePath as h, deleteModel as i, writeModel as l, resolveContentDir as m, checkReferences as n, listModels as o, readContent as p, countEntries as r, readModel as s, FIELD_TYPE_ENUM as t, deleteContent as u, serializeFrontmatter as v, validateSlug$1 as x, validateEntryId$1 as y };
1287
+ export { validateLocale$1 as C, LocalReader as E, validateEntryId$1 as S, writeContent as T, resolveContentDir as _, deleteModel as a, resolveMdFilePath as b, listModels as c, validateModelDefinition as d, writeModel as f, readContent as g, parseFrontmatter as h, countEntries as i, readModel as l, listContent as m, MODEL_FIELD_ORDER$1 as n, fieldDefZodSchema as o, deleteContent as p, checkReferences as r, inferTitleField as s, FIELD_TYPE_ENUM as t, titleFieldIssues as u, resolveJsonFilePath as v, validateSlug$1 as w, serializeFrontmatter as x, resolveLocaleStrategy as y };
1144
1288
 
1145
- //# sourceMappingURL=model-manager-DP2CZiMT.mjs.map
1289
+ //# sourceMappingURL=model-manager-DgyKMjLN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-manager-DgyKMjLN.mjs","names":["validateLocale","validateEntryId","validateSlug","tryReadJsonViaReader"],"sources":["../src/providers/local/reader.ts","../src/core/content-manager.ts","../src/core/model-manager.ts"],"sourcesContent":["import { access, readdir, readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport type { RepoReader } from '../../core/contracts/index.js'\n\n/**\n * LocalReader — `RepoReader` backed by the local filesystem.\n *\n * Paths may be absolute or relative to `projectRoot` (`node:path/resolve`\n * handles both). The `ref` parameter is accepted for interface compatibility\n * but ignored because LocalReader always reads from the working tree.\n *\n * Phase 1: provided as plumbing; core ops still use direct `fs` calls.\n * Phase 2 routes ops through this reader (and through GitHubProvider's reader\n * in Phase 5) so the same op surface works on every backing store.\n */\nexport class LocalReader implements RepoReader {\n constructor(public readonly projectRoot: string) {}\n\n async readFile(path: string, _ref?: string): Promise<string> {\n return readFile(resolve(this.projectRoot, path), 'utf-8')\n }\n\n async listDirectory(path: string, _ref?: string): Promise<string[]> {\n try {\n return await readdir(resolve(this.projectRoot, path))\n } catch {\n return []\n }\n }\n\n async fileExists(path: string, _ref?: string): Promise<boolean> {\n try {\n await access(resolve(this.projectRoot, path))\n return true\n } catch {\n return false\n }\n }\n}\n","import type { ModelDefinition, ContentrainConfig, EntryMeta, LocaleStrategy, DocumentEntry, Vocabulary } from '@contentrain/types'\nimport { validateSlug, validateEntryId, validateLocale, generateEntryId, parseMarkdownFrontmatter, serializeMarkdownFrontmatter } from '@contentrain/types'\nimport { join } from 'node:path'\nimport { rm } from 'node:fs/promises'\nimport { contentrainDir, readDir, readJson, readText, writeJson, writeText } from '../util/fs.js'\nimport { readMeta, writeMeta, deleteMeta, mergeEntryMeta } from './meta-manager.js'\nimport { readModel } from './model-manager.js'\nimport type { RepoReader } from './contracts/index.js'\nimport { contentDirPath, contentFilePath, documentFilePath } from './ops/paths.js'\n\n// Re-export for backward compatibility (MCP internal consumers)\nexport { validateSlug, validateEntryId, validateLocale }\nexport { parseMarkdownFrontmatter as parseFrontmatter, serializeMarkdownFrontmatter as serializeFrontmatter } from '@contentrain/types'\n\n/** Keys named individually in a replacement advisory before it collapses to a count. */\nconst MAX_REPORTED_KEYS = 5\n\n// ─── Content paths ───\n//\n// These take the narrowest `Pick<ModelDefinition, …>` each one actually reads,\n// mirroring `ops/paths.ts`. Path resolution has nothing to do with a model's\n// title or schema, and demanding a whole `ModelDefinition` pushed callers that\n// only have a path-shaped fragment into `as ModelDefinition` casts — which then\n// hide a genuinely missing required property from the compiler.\n\nexport type ContentPathModel = Pick<ModelDefinition, 'id' | 'domain' | 'content_path'>\nexport type LocaleStrategyModel = Pick<ModelDefinition, 'locale_strategy'>\nexport type ContentFileModel = Pick<ModelDefinition, 'id' | 'i18n' | 'locale_strategy'>\n\nexport function resolveContentDir(projectRoot: string, model: ContentPathModel): string {\n if (model.content_path) {\n return join(projectRoot, model.content_path)\n }\n return join(contentrainDir(projectRoot), 'content', model.domain, model.id)\n}\n\nexport function resolveLocaleStrategy(model: LocaleStrategyModel): LocaleStrategy {\n return model.locale_strategy ?? 'file'\n}\n\n/** Build the file path for a JSON content file (singleton/collection/dictionary) */\nexport function resolveJsonFilePath(dir: string, model: ContentFileModel, locale: string): string {\n // When i18n is disabled, always use data.json (locale parameter is ignored)\n if (!model.i18n) return join(dir, 'data.json')\n\n switch (resolveLocaleStrategy(model)) {\n case 'suffix': return join(dir, `${model.id}.${locale}.json`)\n case 'directory': return join(dir, locale, `${model.id}.json`)\n case 'none': return join(dir, `${model.id}.json`)\n case 'file':\n default: return join(dir, `${locale}.json`)\n }\n}\n\n/** Build the file path for a markdown document */\nexport function resolveMdFilePath(dir: string, model: Pick<ModelDefinition, 'i18n' | 'locale_strategy'>, locale: string, slug: string): string {\n // When i18n is disabled, always use {slug}.md (locale parameter is ignored)\n if (!model.i18n) return join(dir, `${slug}.md`)\n\n switch (resolveLocaleStrategy(model)) {\n case 'suffix': return join(dir, `${slug}.${locale}.md`)\n case 'directory': return join(dir, locale, `${slug}.md`)\n case 'none': return join(dir, `${slug}.md`)\n case 'file':\n default: return join(dir, slug, `${locale}.md`)\n }\n}\n\n// ─── Types ───\n\nexport interface ContentEntry {\n id?: string\n slug?: string\n locale?: string\n data: Record<string, unknown>\n}\n\nexport interface WriteResult {\n action: 'created' | 'updated'\n id?: string\n slug?: string\n locale: string\n advisories?: string[]\n}\n\nexport interface DeleteOpts {\n id?: string\n slug?: string\n locale?: string\n keys?: string[]\n /** `config.locales.default` — places a non-i18n model's single meta record. */\n defaultLocale: string\n}\n\nexport interface ListOpts {\n locale?: string\n filter?: Record<string, unknown>\n resolve?: boolean\n limit?: number\n offset?: number\n}\n\n// ─── writeContent ───\n\nexport async function writeContent(\n projectRoot: string,\n model: ModelDefinition,\n entries: ContentEntry[],\n config: ContentrainConfig,\n vocabulary?: Vocabulary | null,\n): Promise<WriteResult[]> {\n const results: WriteResult[] = []\n const defaultLocale = config.locales.default\n\n for (const entry of entries) {\n const locale = entry.locale ?? defaultLocale\n\n // Validate locale\n const localeErr = validateLocale(locale, config)\n if (localeErr) throw new Error(localeErr)\n\n // Validate entry ID if provided\n if (entry.id) {\n const idErr = validateEntryId(entry.id)\n if (idErr) throw new Error(idErr)\n }\n\n // Validate slug if provided\n if (entry.slug) {\n const slugErr = validateSlug(entry.slug)\n if (slugErr) throw new Error(slugErr)\n }\n\n switch (model.kind) {\n case 'singleton': {\n const filePath = resolveJsonFilePath(resolveContentDir(projectRoot, model), model, locale)\n await writeJson(filePath, entry.data)\n const prevMeta = await readMeta(projectRoot, model, { locale, defaultLocale }) as EntryMeta | null\n await writeMeta(projectRoot, model, { locale, defaultLocale }, mergeEntryMeta(prevMeta ?? undefined, entry.data))\n results.push({ action: 'updated', locale })\n break\n }\n\n case 'collection': {\n const isNew = !entry.id\n const id = entry.id ?? generateEntryId()\n const filePath = resolveJsonFilePath(resolveContentDir(projectRoot, model), model, locale)\n const existing = await readJson<Record<string, Record<string, unknown>>>(filePath) ?? {}\n\n const action: 'created' | 'updated' = (isNew || !(id in existing)) ? 'created' : 'updated'\n existing[id] = entry.data\n\n // Sort by entry ID for canonical output\n const sorted: Record<string, Record<string, unknown>> = {}\n for (const key of Object.keys(existing).toSorted()) {\n sorted[key] = existing[key]!\n }\n\n await writeJson(filePath, sorted)\n const prevMetaMap = await readMeta(projectRoot, model, { locale, defaultLocale }) as Record<string, EntryMeta> | null\n await writeMeta(projectRoot, model, { locale, entryId: id, defaultLocale }, mergeEntryMeta(prevMetaMap?.[id], entry.data))\n results.push({ action, id, locale })\n break\n }\n\n case 'document': {\n const slug = entry.slug ?? entry.data['slug'] as string\n if (!slug) throw new Error('Document entries require a slug')\n const slugErr = validateSlug(slug)\n if (slugErr) throw new Error(slugErr)\n\n const incomingFm = { ...entry.data }\n const bodySent = 'body' in incomingFm\n const incomingBody = (incomingFm['body'] as string | undefined) ?? ''\n delete incomingFm['body']\n if (!incomingFm['slug']) incomingFm['slug'] = slug\n\n // Check if existing\n const docPath = resolveMdFilePath(resolveContentDir(projectRoot, model), model, locale, slug)\n const existingRaw = await readText(docPath)\n const action: 'created' | 'updated' = existingRaw ? 'updated' : 'created'\n\n // Merge with what is there, matching `planContentSave`. This path is\n // reached by scaffold and by normalize extract; extracting into a model\n // that already has documents would otherwise replace them wholesale.\n const existingDoc = existingRaw ? parseMarkdownFrontmatter(existingRaw) : null\n const fmData = { ...existingDoc?.frontmatter, ...incomingFm }\n const bodyContent = bodySent ? incomingBody : (existingDoc?.body ?? '')\n\n const mdContent = serializeMarkdownFrontmatter(fmData, bodyContent)\n await writeText(docPath, mdContent)\n const prevMeta = await readMeta(projectRoot, model, { locale, slug, defaultLocale }) as EntryMeta | null\n await writeMeta(projectRoot, model, { locale, slug, defaultLocale }, mergeEntryMeta(prevMeta ?? undefined, entry.data))\n results.push({ action, slug, locale })\n break\n }\n\n case 'dictionary': {\n const filePath = resolveJsonFilePath(resolveContentDir(projectRoot, model), model, locale)\n const existing = await readJson<Record<string, string>>(filePath) ?? {}\n // Duplicate value advisory: warn when a new key maps to a value that already exists\n const advisories: string[] = []\n\n // Replacing a value is reported, not refused — see the same block in\n // `planContentSave`. Correcting a translation is a content decision.\n const incoming = entry.data as Record<string, string>\n const replaced = Object.keys(incoming).filter(\n k => k in existing && existing[k] !== incoming[k],\n )\n if (replaced.length > 0) {\n const shown = replaced.slice(0, MAX_REPORTED_KEYS)\n const detail = shown.map(k => `\"${k}\": \"${existing[k]}\" → \"${incoming[k]}\"`).join(', ')\n const more = replaced.length > shown.length ? `, and ${replaced.length - shown.length} more` : ''\n advisories.push(\n `Dictionary \"${model.id}\" (${locale}): replaced ${replaced.length} existing value(s) — ${detail}${more}.`,\n )\n }\n const reverseMap = new Map<string, string>()\n for (const [k, v] of Object.entries(existing)) {\n reverseMap.set(v, k)\n }\n for (const [newKey, newValue] of Object.entries(entry.data as Record<string, string>)) {\n if (newKey in existing) continue\n const existingKey = reverseMap.get(newValue as string)\n if (existingKey && existingKey !== newKey) {\n advisories.push(\n `Value \"${newValue}\" already exists as key \"${existingKey}\". Consider reusing instead of creating \"${newKey}\".`,\n )\n }\n }\n\n // Vocabulary cross-reference: warn when a value matches a known vocabulary term\n if (vocabulary && Object.keys(vocabulary.terms).length > 0) {\n for (const [newKey, newValue] of Object.entries(entry.data as Record<string, string>)) {\n if (newKey in existing) continue\n for (const [, translations] of Object.entries(vocabulary.terms)) {\n if (Object.values(translations).includes(newValue as string)) {\n advisories.push(\n `Value \"${newValue}\" matches a vocabulary term. Use the canonical form for consistency.`,\n )\n break\n }\n }\n }\n }\n\n const merged = { ...existing, ...entry.data as Record<string, string> }\n await writeJson(filePath, merged)\n const prevMeta = await readMeta(projectRoot, model, { locale, defaultLocale }) as EntryMeta | null\n await writeMeta(projectRoot, model, { locale, defaultLocale }, mergeEntryMeta(prevMeta ?? undefined, entry.data))\n results.push({ action: 'updated', locale, ...(advisories.length > 0 ? { advisories } : {}) })\n break\n }\n }\n }\n\n return results\n}\n\n// ─── deleteContent ───\n\nexport async function deleteContent(\n projectRoot: string,\n model: ModelDefinition,\n opts: DeleteOpts,\n): Promise<string[]> {\n // A non-i18n model stores content locale-agnostically in data.json with a\n // single meta record at the default locale, so a locale-scoped delete is\n // meaningless and destructive (the locale maps onto data.json + the default\n // meta, deleting the shared content and the wrong meta). Reject it; mirrors\n // the same guard in the plan API (`planContentDelete`).\n if (!model.i18n && opts.locale) {\n throw new Error(\n `Model \"${model.id}\" has i18n disabled — its content is locale-agnostic (stored in data.json), `\n + 'so a locale-scoped delete is invalid. Omit \"locale\" to delete the entry, '\n + 'or run contentrain_validate fix:true to remove stray per-locale meta files.',\n )\n }\n\n const removed: string[] = []\n const cDir = resolveContentDir(projectRoot, model)\n\n switch (model.kind) {\n case 'collection': {\n if (!opts.id) throw new Error('Collection delete requires an entry ID')\n const locales = opts.locale\n ? [opts.locale]\n : (await readDir(cDir)).filter(f => f.endsWith('.json')).map(f => f.replace('.json', '').replace(`${model.id}.`, ''))\n\n for (const loc of locales) {\n const filePath = resolveJsonFilePath(cDir, model, loc)\n const data = await readJson<Record<string, unknown>>(filePath)\n if (data && opts.id in data) {\n delete data[opts.id]\n await writeJson(filePath, data)\n removed.push(`content/${model.domain}/${model.id}/${loc}.json#${opts.id}`)\n }\n }\n\n for (const loc of locales) {\n await deleteMeta(projectRoot, model, { locale: loc, entryId: opts.id, defaultLocale: opts.defaultLocale })\n }\n break\n }\n\n case 'document': {\n if (!opts.slug) throw new Error('Document delete requires a slug')\n const slugDelErr = validateSlug(opts.slug)\n if (slugDelErr) throw new Error(slugDelErr)\n\n const strategy = resolveLocaleStrategy(model)\n if (!model.i18n) {\n // No i18n: single {slug}.md file\n await rm(join(cDir, `${opts.slug}.md`), { force: true })\n } else if (strategy === 'file') {\n // slug is a directory — remove entire slug directory\n await rm(join(cDir, opts.slug), { recursive: true, force: true })\n } else if (opts.locale) {\n // Remove specific locale file\n const filePath = resolveMdFilePath(cDir, model, opts.locale, opts.slug)\n await rm(filePath, { force: true })\n } else {\n // Remove all locale files for this slug\n const files = await readDir(strategy === 'directory' ? cDir : cDir)\n for (const f of files) {\n if (strategy === 'suffix' && f.startsWith(`${opts.slug}.`) && f.endsWith('.md')) {\n await rm(join(cDir, f), { force: true })\n } else if (strategy === 'directory') {\n // f is a locale dir — remove slug.md from it\n await rm(join(cDir, f, `${opts.slug}.md`), { force: true })\n } else if (strategy === 'none') {\n if (f === `${opts.slug}.md`) await rm(join(cDir, f), { force: true })\n }\n }\n }\n removed.push(`${model.content_path ?? `content/${model.domain}/${model.id}`}/${opts.slug}`)\n\n await deleteMeta(projectRoot, model, { slug: opts.slug, locale: opts.locale, defaultLocale: opts.defaultLocale })\n break\n }\n\n case 'singleton': {\n if (model.i18n && !opts.locale) throw new Error('Singleton delete requires a locale when i18n is enabled')\n const locale = opts.locale ?? 'data'\n const filePath = resolveJsonFilePath(cDir, model, locale)\n await rm(filePath, { force: true })\n removed.push(model.i18n\n ? `content/${model.domain}/${model.id}/${locale}.json`\n : `content/${model.domain}/${model.id}/data.json`)\n await deleteMeta(projectRoot, model, { locale: model.i18n ? locale : undefined, defaultLocale: opts.defaultLocale })\n break\n }\n\n case 'dictionary': {\n if (model.i18n && !opts.locale) throw new Error('Dictionary delete requires a locale when i18n is enabled')\n const locale = opts.locale ?? 'data'\n const filePath = resolveJsonFilePath(cDir, model, locale)\n\n if (opts.keys?.length) {\n // Delete specific keys from dictionary\n const existing = await readJson<Record<string, string>>(filePath) ?? {}\n const notFound: string[] = []\n for (const key of opts.keys) {\n if (key in existing) {\n delete existing[key]\n } else {\n notFound.push(key)\n }\n }\n if (notFound.length > 0) {\n throw new Error(`Dictionary \"${model.id}\" (${locale}): keys not found — [${notFound.join(', ')}]`)\n }\n await writeJson(filePath, existing)\n removed.push(...opts.keys.map(k => `${model.id}/${locale}:${k}`))\n } else {\n // Delete entire locale file\n await rm(filePath, { force: true })\n removed.push(model.i18n\n ? `content/${model.domain}/${model.id}/${locale}.json`\n : `content/${model.domain}/${model.id}/data.json`)\n await deleteMeta(projectRoot, model, { locale: model.i18n ? locale : undefined, defaultLocale: opts.defaultLocale })\n }\n break\n }\n }\n\n return removed\n}\n\n// ─── listContent ───\n\n/**\n * List content entries for a model. Dual signature:\n *\n * - `listContent(projectRoot, model, opts, config)` — legacy local flow,\n * uses direct filesystem reads and supports `opts.resolve` for\n * cross-model relation hydration.\n * - `listContent(reader, model, opts, config)` — reader-backed flow for\n * remote providers. Basic list works across all four model kinds.\n * `opts.resolve: true` is rejected with an error on remote readers\n * because the cross-model walk requires local filesystem access.\n *\n * The reader-based function lives in {@link listContentViaReader}; the\n * projectRoot-based entry point continues to call the legacy body to\n * preserve bit-for-bit behaviour for every existing caller.\n */\nexport function listContent(\n projectRoot: string,\n model: ModelDefinition,\n opts: ListOpts,\n config: ContentrainConfig,\n): Promise<unknown>\nexport function listContent(\n reader: RepoReader,\n model: ModelDefinition,\n opts: ListOpts,\n config: ContentrainConfig,\n): Promise<unknown>\nexport async function listContent(\n input: string | RepoReader,\n model: ModelDefinition,\n opts: ListOpts,\n config: ContentrainConfig,\n): Promise<unknown> {\n if (typeof input !== 'string') {\n return listContentViaReader(input, model, opts, config)\n }\n return listContentLocal(input, model, opts, config)\n}\n\nasync function listContentLocal(\n projectRoot: string,\n model: ModelDefinition,\n opts: ListOpts,\n config: ContentrainConfig,\n): Promise<unknown> {\n const cDir = resolveContentDir(projectRoot, model)\n const locale = opts.locale ?? config.locales.default\n\n switch (model.kind) {\n case 'singleton': {\n const data = await readJson<Record<string, unknown>>(resolveJsonFilePath(cDir, model, locale))\n return { kind: 'singleton', data: data ?? {}, locale }\n }\n\n case 'collection': {\n const data = await readJson<Record<string, Record<string, unknown>>>(resolveJsonFilePath(cDir, model, locale)) ?? {}\n let entries: Array<Record<string, unknown>> = Object.entries(data).map(([id, fields]) => {\n const entry: Record<string, unknown> = { id }\n Object.assign(entry, fields)\n return entry\n })\n\n // Filter\n if (opts.filter) {\n entries = entries.filter(entry => {\n for (const [key, value] of Object.entries(opts.filter!)) {\n if (entry[key] !== value) return false\n }\n return true\n })\n }\n\n const total = entries.length\n\n // Pagination\n const offset = opts.offset ?? 0\n const limit = opts.limit ?? entries.length\n entries = entries.slice(offset, offset + limit)\n\n // Resolve relations\n if (opts.resolve && model.fields) {\n entries = await resolveRelations(projectRoot, model, entries, locale)\n }\n\n return { kind: 'collection', data: entries, total, locale, offset, limit }\n }\n\n case 'document': {\n const entries: DocumentEntry[] = []\n const strategy = resolveLocaleStrategy(model)\n\n if (!model.i18n) {\n // No i18n: flat {slug}.md files, no locale in path\n const files = await readDir(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n } else if (strategy === 'file') {\n // Each slug is a subdirectory containing locale.md files\n const slugDirs = await readDir(cDir)\n for (const slug of slugDirs) {\n const raw = await readText(join(cDir, slug, `${locale}.md`))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n } else if (strategy === 'suffix') {\n // Files like {slug}.{locale}.md in flat directory\n const files = await readDir(cDir)\n const suffix = `.${locale}.md`\n for (const f of files) {\n if (!f.endsWith(suffix)) continue\n const slug = f.slice(0, -suffix.length)\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n } else if (strategy === 'directory') {\n // Files in {locale}/ directory as {slug}.md\n const localeDir = join(cDir, locale)\n const files = await readDir(localeDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(localeDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n } else {\n // none — {slug}.md, no locale in filename\n const files = await readDir(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n }\n\n const total = entries.length\n const offset = opts.offset ?? 0\n const limit = opts.limit ?? entries.length\n const paged = entries.slice(offset, offset + limit)\n\n return { kind: 'document', data: paged, total, locale, offset, limit }\n }\n\n case 'dictionary': {\n const data = await readJson<Record<string, string>>(resolveJsonFilePath(cDir, model, locale)) ?? {}\n return { kind: 'dictionary', data, total_keys: Object.keys(data).length, locale }\n }\n }\n}\n\nasync function tryReadJsonViaReader<T>(reader: RepoReader, path: string): Promise<T | null> {\n try {\n return JSON.parse(await reader.readFile(path)) as T\n } catch {\n return null\n }\n}\n\nasync function tryReadTextViaReader(reader: RepoReader, path: string): Promise<string | null> {\n try {\n return await reader.readFile(path)\n } catch {\n return null\n }\n}\n\nasync function listContentViaReader(\n reader: RepoReader,\n model: ModelDefinition,\n opts: ListOpts,\n config: ContentrainConfig,\n): Promise<unknown> {\n if (opts.resolve) {\n throw new Error(\n 'contentrain_content_list with resolve:true requires local filesystem access. '\n + 'Use a LocalProvider (stdio or HTTP+LocalProvider) or omit resolve:true.',\n )\n }\n\n const cDir = contentDirPath(model)\n const locale = opts.locale ?? config.locales.default\n\n switch (model.kind) {\n case 'singleton': {\n const data = await tryReadJsonViaReader<Record<string, unknown>>(reader, contentFilePath(model, locale))\n return { kind: 'singleton', data: data ?? {}, locale }\n }\n\n case 'collection': {\n const data = await tryReadJsonViaReader<Record<string, Record<string, unknown>>>(\n reader,\n contentFilePath(model, locale),\n ) ?? {}\n let entries: Array<Record<string, unknown>> = Object.entries(data).map(([id, fields]) => {\n const entry: Record<string, unknown> = { id }\n Object.assign(entry, fields)\n return entry\n })\n\n if (opts.filter) {\n entries = entries.filter(entry => {\n for (const [key, value] of Object.entries(opts.filter!)) {\n if (entry[key] !== value) return false\n }\n return true\n })\n }\n\n const total = entries.length\n const offset = opts.offset ?? 0\n const limit = opts.limit ?? entries.length\n entries = entries.slice(offset, offset + limit)\n\n return { kind: 'collection', data: entries, total, locale, offset, limit }\n }\n\n case 'document': {\n const entries: DocumentEntry[] = []\n const strategy = resolveLocaleStrategy(model)\n\n const collectEntry = async (relPath: string, slug: string): Promise<void> => {\n const raw = await tryReadTextViaReader(reader, relPath)\n if (!raw) return\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n entries.push({ slug, frontmatter, body })\n }\n\n if (!model.i18n) {\n const files = await reader.listDirectory(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n await collectEntry(documentFilePath(model, locale, f.replace(/\\.md$/u, '')), f.replace(/\\.md$/u, ''))\n }\n } else if (strategy === 'file') {\n const slugDirs = await reader.listDirectory(cDir)\n for (const slug of slugDirs) {\n await collectEntry(documentFilePath(model, locale, slug), slug)\n }\n } else if (strategy === 'suffix') {\n const files = await reader.listDirectory(cDir)\n const suffix = `.${locale}.md`\n for (const f of files) {\n if (!f.endsWith(suffix)) continue\n const slug = f.slice(0, -suffix.length)\n await collectEntry(documentFilePath(model, locale, slug), slug)\n }\n } else if (strategy === 'directory') {\n const files = await reader.listDirectory(`${cDir}/${locale}`)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace(/\\.md$/u, '')\n await collectEntry(documentFilePath(model, locale, slug), slug)\n }\n } else {\n const files = await reader.listDirectory(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace(/\\.md$/u, '')\n await collectEntry(documentFilePath(model, locale, slug), slug)\n }\n }\n\n const total = entries.length\n const offset = opts.offset ?? 0\n const limit = opts.limit ?? entries.length\n const paged = entries.slice(offset, offset + limit)\n\n return { kind: 'document', data: paged, total, locale, offset, limit }\n }\n\n case 'dictionary': {\n const data = await tryReadJsonViaReader<Record<string, string>>(reader, contentFilePath(model, locale)) ?? {}\n return { kind: 'dictionary', data, total_keys: Object.keys(data).length, locale }\n }\n }\n}\n\n// ─── readContent (for external use / relation resolving) ───\n\nexport async function readContent(\n projectRoot: string,\n model: ModelDefinition,\n opts: { locale: string; entryId?: string; slug?: string },\n): Promise<unknown> {\n const cDir = resolveContentDir(projectRoot, model)\n\n switch (model.kind) {\n case 'singleton':\n return readJson<Record<string, unknown>>(resolveJsonFilePath(cDir, model, opts.locale))\n\n case 'collection': {\n if (!opts.entryId) return null\n const data = await readJson<Record<string, Record<string, unknown>>>(resolveJsonFilePath(cDir, model, opts.locale))\n return data?.[opts.entryId] ? { id: opts.entryId, ...data[opts.entryId] } : null\n }\n\n case 'document': {\n if (!opts.slug) return null\n const raw = await readText(resolveMdFilePath(cDir, model, opts.locale, opts.slug))\n if (!raw) return null\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n return { slug: opts.slug, ...frontmatter, body }\n }\n\n case 'dictionary':\n return readJson<Record<string, string>>(resolveJsonFilePath(cDir, model, opts.locale))\n }\n}\n\n// ─── Relation resolving ───\n\nasync function resolveRelations(\n projectRoot: string,\n model: ModelDefinition,\n entries: Array<Record<string, unknown>>,\n locale: string,\n): Promise<Array<Record<string, unknown>>> {\n if (!model.fields) return entries\n\n const relationFields: Array<{ name: string; targetModels: string[]; multi: boolean }> = []\n for (const [name, field] of Object.entries(model.fields)) {\n if (field.type === 'relation' || field.type === 'relations') {\n const targets = Array.isArray(field.model) ? field.model : field.model ? [field.model] : []\n relationFields.push({ name, targetModels: targets, multi: field.type === 'relations' })\n }\n }\n\n if (relationFields.length === 0) return entries\n\n // Load target model contents into cache (with circular reference protection)\n const targetCache: Record<string, Record<string, Record<string, unknown>>> = {}\n const visited = new Set<string>([model.id])\n\n for (const rf of relationFields) {\n for (const targetModelId of rf.targetModels) {\n if (targetCache[targetModelId] || visited.has(targetModelId)) continue\n visited.add(targetModelId)\n\n const targetModel = await readModel(projectRoot, targetModelId)\n if (!targetModel) continue\n\n if (targetModel.kind === 'collection') {\n const targetData = await readJson<Record<string, Record<string, unknown>>>(\n resolveJsonFilePath(resolveContentDir(projectRoot, targetModel), targetModel, locale),\n ) ?? {}\n targetCache[targetModelId] = targetData\n } else if (targetModel.kind === 'document') {\n // Build slug-keyed cache by listing document entries for this locale\n const docCache: Record<string, Record<string, unknown>> = {}\n const cDir = resolveContentDir(projectRoot, targetModel)\n const strategy = resolveLocaleStrategy(targetModel)\n\n if (!targetModel.i18n) {\n const files = await readDir(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n docCache[slug] = { slug, ...frontmatter, body }\n }\n } else if (strategy === 'file') {\n const slugDirs = await readDir(cDir)\n for (const slug of slugDirs) {\n const raw = await readText(join(cDir, slug, `${locale}.md`))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n docCache[slug] = { slug, ...frontmatter, body }\n }\n } else if (strategy === 'suffix') {\n const files = await readDir(cDir)\n const suffix = `.${locale}.md`\n for (const f of files) {\n if (!f.endsWith(suffix)) continue\n const slug = f.slice(0, -suffix.length)\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n docCache[slug] = { slug, ...frontmatter, body }\n }\n } else if (strategy === 'directory') {\n const localeDir = join(cDir, locale)\n const files = await readDir(localeDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(localeDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n docCache[slug] = { slug, ...frontmatter, body }\n }\n } else {\n // 'none' strategy\n const files = await readDir(cDir)\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n const slug = f.replace('.md', '')\n const raw = await readText(join(cDir, f))\n if (!raw) continue\n const { frontmatter, body } = parseMarkdownFrontmatter(raw)\n docCache[slug] = { slug, ...frontmatter, body }\n }\n }\n\n targetCache[targetModelId] = docCache\n }\n }\n }\n\n return entries.map(entry => {\n const resolved = { ...entry }\n for (const rf of relationFields) {\n const value = resolved[rf.name]\n if (!value) continue\n\n if (rf.multi && Array.isArray(value)) {\n resolved[rf.name] = value.map(id => {\n for (const targetModelId of rf.targetModels) {\n const cached = targetCache[targetModelId]?.[id as string]\n if (cached) return { id, ...cached }\n }\n return id\n })\n } else if (typeof value === 'string') {\n for (const targetModelId of rf.targetModels) {\n const cached = targetCache[targetModelId]?.[value]\n if (cached) {\n resolved[rf.name] = { id: value, ...cached }\n break\n }\n }\n }\n }\n return resolved\n })\n}\n","import type { FieldType, ModelDefinition, ModelSummary } from '@contentrain/types'\nimport { DICTIONARY_TITLE_FIELD, isTitleFieldType, LOCALE_PATTERN, MODEL_FIELD_ORDER, TITLE_FIELD_TYPES } from '@contentrain/types'\nimport { join } from 'node:path'\nimport { rm } from 'node:fs/promises'\nimport { z } from 'zod'\nimport { contentrainDir, ensureDir, readDir, readJson, writeJson } from '../util/fs.js'\nimport type { RepoReader } from './contracts/index.js'\nimport { LocalReader } from '../providers/local/reader.js'\nimport { resolveContentDir, resolveLocaleStrategy } from './content-manager.js'\nimport { contentDirPath } from './ops/paths.js'\n\nexport type { ModelSummary } from '@contentrain/types'\n// Re-exported so `packages/rules` and `packages/skills` — which devDep\n// @contentrain/mcp but not @contentrain/types — can assert docs parity\n// against the canonical key list without taking a new dependency.\nexport { MODEL_FIELD_ORDER } from '@contentrain/types'\n\nconst MODELS_DIR_PATH = '.contentrain/models'\n\nasync function tryReadJsonViaReader<T>(reader: RepoReader, path: string): Promise<T | null> {\n try {\n return JSON.parse(await reader.readFile(path)) as T\n } catch {\n return null\n }\n}\n\n/**\n * List every model defined under `.contentrain/models/*.json`.\n *\n * Accepts either a legacy `projectRoot` string (filesystem walk) or any\n * `RepoReader` — HTTP-hosted callers pass their `GitHubProvider` so the\n * same helper resolves model metadata over the Git Data API.\n */\nexport function listModels(projectRoot: string): Promise<ModelSummary[]>\nexport function listModels(reader: RepoReader): Promise<ModelSummary[]>\nexport async function listModels(input: string | RepoReader): Promise<ModelSummary[]> {\n let files: string[]\n let load: (file: string) => Promise<ModelDefinition | null>\n\n if (typeof input === 'string') {\n const modelsDir = join(contentrainDir(input), 'models')\n files = await readDir(modelsDir)\n load = file => readJson<ModelDefinition>(join(modelsDir, file))\n } else {\n files = await input.listDirectory(MODELS_DIR_PATH)\n load = file => tryReadJsonViaReader<ModelDefinition>(input, `${MODELS_DIR_PATH}/${file}`)\n }\n\n const jsonFiles = files.filter(f => f.endsWith('.json'))\n const models = await Promise.all(jsonFiles.map(load))\n\n return models\n .filter((m): m is ModelDefinition => m !== null && !!m.id)\n .map(model => ({\n id: model.id,\n kind: model.kind,\n domain: model.domain,\n i18n: model.i18n,\n fields: model.fields ? Object.keys(model.fields).length : 0,\n }))\n .toSorted((a, b) => a.id.localeCompare(b.id, 'en'))\n}\n\n/**\n * Read a single model definition. Same dual signature as {@link listModels}.\n */\nexport function readModel(projectRoot: string, modelId: string): Promise<ModelDefinition | null>\nexport function readModel(reader: RepoReader, modelId: string): Promise<ModelDefinition | null>\nexport async function readModel(input: string | RepoReader, modelId: string): Promise<ModelDefinition | null> {\n if (typeof input === 'string') {\n const filePath = join(contentrainDir(input), 'models', `${modelId}.json`)\n return readJson<ModelDefinition>(filePath)\n }\n return tryReadJsonViaReader<ModelDefinition>(input, `${MODELS_DIR_PATH}/${modelId}.json`)\n}\n\nasync function countDocumentFileStrategy(\n reader: RepoReader,\n contentDir: string,\n entries: string[],\n): Promise<{ total: number, locales: Record<string, number> }> {\n const locales: Record<string, number> = {}\n let total = 0\n\n const results = await Promise.all(\n entries.map(async (entry) => {\n const localeFiles = await reader.listDirectory(`${contentDir}/${entry}`)\n return localeFiles\n .map(lf => lf.replace(/\\.(json|md|mdx)$/, ''))\n .filter((locale, i) => locale !== localeFiles[i])\n }),\n )\n\n for (const entryLocales of results) {\n for (const locale of entryLocales) {\n locales[locale] = (locales[locale] ?? 0) + 1\n total++\n }\n }\n\n return { total, locales }\n}\n\nasync function countDocumentSuffixStrategy(\n _reader: RepoReader,\n _contentDir: string,\n files: string[],\n): Promise<{ total: number, locales: Record<string, number> }> {\n const locales: Record<string, number> = {}\n const slugsByLocale: Record<string, Set<string>> = {}\n\n for (const f of files) {\n if (!f.endsWith('.md')) continue\n // Pattern: {slug}.{locale}.md\n const match = f.match(/^(.+)\\.([a-z]{2}(?:-[A-Z]{2})?)\\.md$/)\n if (!match) continue\n const locale = match[2]!\n if (!slugsByLocale[locale]) slugsByLocale[locale] = new Set()\n slugsByLocale[locale].add(match[1]!)\n }\n\n let total = 0\n for (const [locale, slugs] of Object.entries(slugsByLocale)) {\n locales[locale] = slugs.size\n total += slugs.size\n }\n\n return { total, locales }\n}\n\nasync function countDocumentDirectoryStrategy(\n reader: RepoReader,\n contentDir: string,\n localeDirs: string[],\n): Promise<{ total: number, locales: Record<string, number> }> {\n const locales: Record<string, number> = {}\n let total = 0\n\n const results = await Promise.all(\n localeDirs.map(async (localeDir) => {\n const files = await reader.listDirectory(`${contentDir}/${localeDir}`)\n const mdFiles = files.filter(f => f.endsWith('.md'))\n return { locale: localeDir, count: mdFiles.length }\n }),\n )\n\n for (const { locale, count } of results) {\n locales[locale] = count\n total += count\n }\n\n return { total, locales }\n}\n\nasync function countDocumentNoneStrategy(\n reader: RepoReader,\n modelId: string,\n files: string[],\n i18n: boolean,\n): Promise<{ total: number, locales: Record<string, number> }> {\n const mdFiles = files.filter(f => f.endsWith('.md'))\n\n if (!i18n) {\n return { total: mdFiles.length, locales: { _: mdFiles.length } }\n }\n\n // With i18n + none strategy, content files have no locale info.\n // Use meta/{modelId}/{slug}/ directories to determine locale counts.\n const metaDir = `.contentrain/meta/${modelId}`\n const locales: Record<string, number> = {}\n let total = 0\n\n const slugs = mdFiles.map(f => f.replace('.md', ''))\n const results = await Promise.all(\n slugs.map(async (slug) => {\n const metaFiles = await reader.listDirectory(`${metaDir}/${slug}`)\n return metaFiles\n .filter(f => f.endsWith('.json'))\n .map(f => f.replace('.json', ''))\n }),\n )\n\n for (const slugLocales of results) {\n for (const locale of slugLocales) {\n locales[locale] = (locales[locale] ?? 0) + 1\n total++\n }\n }\n\n return { total, locales }\n}\n\nasync function countCollectionEntries(\n reader: RepoReader,\n contentDir: string,\n jsonFiles: string[],\n): Promise<{ total: number, locales: Record<string, number> }> {\n const locales: Record<string, number> = {}\n let total = 0\n\n const results = await Promise.all(\n jsonFiles.map(async (file) => {\n const locale = file.replace(/\\.json$/, '')\n const data = await tryReadJsonViaReader<Record<string, unknown>>(reader, `${contentDir}/${file}`)\n return { locale, count: data ? Object.keys(data).length : 0 }\n }),\n )\n\n for (const { locale, count } of results) {\n locales[locale] = count\n total += count\n }\n\n return { total, locales }\n}\n\n/**\n * Count content entries across locales for a model.\n *\n * Accepts either a legacy `projectRoot` string (wraps LocalReader internally)\n * or any `RepoReader` — so remote providers (GitHubProvider) feed the same\n * counting logic via the Git Data API.\n */\nexport function countEntries(\n projectRoot: string,\n model: ModelDefinition,\n): Promise<{ total: number, locales: Record<string, number> }>\nexport function countEntries(\n reader: RepoReader,\n model: ModelDefinition,\n): Promise<{ total: number, locales: Record<string, number> }>\nexport async function countEntries(\n input: string | RepoReader,\n model: ModelDefinition,\n): Promise<{ total: number, locales: Record<string, number> }> {\n const reader: RepoReader = typeof input === 'string' ? new LocalReader(input) : input\n const cDir = contentDirPath(model)\n const strategy = resolveLocaleStrategy(model)\n const files = await reader.listDirectory(cDir)\n\n if (model.kind === 'document') {\n if (!model.i18n) {\n // No i18n: flat {slug}.md files\n return countDocumentNoneStrategy(reader, model.id, files, false)\n }\n\n switch (strategy) {\n case 'file':\n return countDocumentFileStrategy(reader, cDir, files)\n case 'suffix':\n return countDocumentSuffixStrategy(reader, cDir, files)\n case 'directory':\n return countDocumentDirectoryStrategy(reader, cDir, files)\n case 'none':\n return countDocumentNoneStrategy(reader, model.id, files, true)\n }\n }\n\n if (model.kind === 'collection') {\n if (!model.i18n) {\n // Non-i18n: single data.json\n const jsonFiles = files.filter(f => f.endsWith('.json'))\n return countCollectionEntries(reader, cDir, jsonFiles)\n }\n switch (strategy) {\n case 'suffix': {\n // Files: {model}.{locale}.json\n const jsonFiles = files.filter(f => f.endsWith('.json'))\n const locales: Record<string, number> = {}\n for (const f of jsonFiles) {\n const match = f.match(/^.+\\.([a-z]{2}(?:-[A-Z]{2})?)\\.json$/)\n if (match) {\n const data = await tryReadJsonViaReader<Record<string, unknown>>(reader, `${cDir}/${f}`)\n locales[match[1]!] = data ? Object.keys(data).length : 0\n }\n }\n const total = Object.values(locales).reduce((a, b) => a + b, 0)\n return { total, locales }\n }\n case 'directory': {\n // Dirs: {locale}/... containing json files\n const locales: Record<string, number> = {}\n let total = 0\n for (const localeDir of files) {\n const subFiles = await reader.listDirectory(`${cDir}/${localeDir}`)\n const jsonFile = subFiles.find(f => f.endsWith('.json'))\n if (jsonFile) {\n const data = await tryReadJsonViaReader<Record<string, unknown>>(reader, `${cDir}/${localeDir}/${jsonFile}`)\n const count = data ? Object.keys(data).length : 0\n locales[localeDir] = count\n total += count\n }\n }\n return { total, locales }\n }\n case 'none': {\n // Single file: {model}.json — count entries inside\n const noneFile = files.find(f => f === `${model.id}.json`)\n if (!noneFile) return { total: 0, locales: {} }\n const data = await tryReadJsonViaReader<Record<string, unknown>>(reader, `${cDir}/${noneFile}`)\n const count = data ? Object.keys(data).length : 0\n return { total: count, locales: { _: count } }\n }\n default: {\n // 'file': {locale}.json\n const jsonFiles = files.filter(f => f.endsWith('.json'))\n return countCollectionEntries(reader, cDir, jsonFiles)\n }\n }\n }\n\n // singleton / dictionary — one entry per locale file\n if (!model.i18n) {\n // Non-i18n: single data.json\n const hasData = files.some(f => f === 'data.json')\n return { total: hasData ? 1 : 0, locales: {} }\n }\n\n switch (strategy) {\n case 'suffix': {\n // Files: {model}.{locale}.json\n const locales: Record<string, number> = {}\n for (const f of files) {\n const match = f.match(/^.+\\.([a-z]{2}(?:-[A-Z]{2})?)\\.json$/)\n if (match) locales[match[1]!] = 1\n }\n return { total: Object.keys(locales).length, locales }\n }\n case 'directory': {\n // Dirs: {locale}/...\n const locales: Record<string, number> = {}\n for (const localeDir of files) {\n const subFiles = await reader.listDirectory(`${cDir}/${localeDir}`)\n if (subFiles.some(f => f.endsWith('.json'))) {\n locales[localeDir] = 1\n }\n }\n return { total: Object.keys(locales).length, locales }\n }\n case 'none': {\n // Single file: {model}.json\n const hasFile = files.some(f => f === `${model.id}.json`)\n return { total: hasFile ? 1 : 0, locales: {} }\n }\n default: {\n // 'file': {locale}.json\n const jsonFiles = files.filter(f => f.endsWith('.json'))\n const locales: Record<string, number> = {}\n for (const file of jsonFiles) {\n locales[file.replace(/\\.json$/, '')] = 1\n }\n return { total: jsonFiles.length, locales }\n }\n }\n}\n\nexport async function writeModel(projectRoot: string, model: ModelDefinition): Promise<void> {\n const filePath = join(contentrainDir(projectRoot), 'models', `${model.id}.json`)\n await writeJson(filePath, model, MODEL_FIELD_ORDER)\n\n // Ensure content and meta directories exist (respects content_path)\n await ensureDir(resolveContentDir(projectRoot, model))\n await ensureDir(join(contentrainDir(projectRoot), 'meta', model.id))\n}\n\nexport async function deleteModel(projectRoot: string, modelId: string): Promise<string[]> {\n const model = await readModel(projectRoot, modelId)\n if (!model) return []\n\n const crDir = contentrainDir(projectRoot)\n const removed: string[] = []\n\n const modelPath = join(crDir, 'models', `${modelId}.json`)\n const contentPath = resolveContentDir(projectRoot, model)\n const metaPath = join(crDir, 'meta', modelId)\n\n await rm(modelPath, { force: true })\n removed.push(`models/${modelId}.json`)\n\n try {\n await rm(contentPath, { recursive: true, force: true })\n removed.push(model.content_path ?? `content/${model.domain}/${modelId}/`)\n } catch {\n // directory may not exist\n }\n\n try {\n await rm(metaPath, { recursive: true, force: true })\n removed.push(`meta/${modelId}/`)\n } catch {\n // directory may not exist\n }\n\n return removed\n}\n\nexport interface ModelReference {\n model: string\n field: string\n type: 'relation' | 'relations'\n}\n\n/**\n * Enumerate models that reference `modelId` through relation or relations\n * fields. Used by `model_delete` to block destructive deletes when other\n * models still depend on the target.\n *\n * Accepts either a legacy `projectRoot` string (LocalReader wraps internally)\n * or any `RepoReader` — remote providers get the same pre-check.\n */\nexport function checkReferences(projectRoot: string, modelId: string): Promise<ModelReference[]>\nexport function checkReferences(reader: RepoReader, modelId: string): Promise<ModelReference[]>\nexport async function checkReferences(\n input: string | RepoReader,\n modelId: string,\n): Promise<ModelReference[]> {\n const summaries = typeof input === 'string' ? await listModels(input) : await listModels(input)\n const others = summaries.filter(s => s.id !== modelId)\n\n const models = await Promise.all(\n others.map(s => typeof input === 'string' ? readModel(input, s.id) : readModel(input, s.id)),\n )\n\n const refs: ModelReference[] = []\n for (const model of models) {\n if (!model?.fields) continue\n\n for (const [fieldName, fieldDef] of Object.entries(model.fields)) {\n if (fieldDef.type !== 'relation' && fieldDef.type !== 'relations') continue\n const targets = Array.isArray(fieldDef.model) ? fieldDef.model : [fieldDef.model]\n if (targets.includes(modelId)) {\n refs.push({ model: model.id, field: fieldName, type: fieldDef.type })\n }\n }\n }\n\n return refs\n}\n\n// ─── Shared Field Type Catalog ───\n\nexport const FIELD_TYPE_ENUM = [\n 'string', 'text', 'email', 'url', 'slug', 'color', 'phone', 'code', 'icon',\n 'markdown', 'richtext',\n 'number', 'integer', 'decimal', 'percent', 'rating',\n 'boolean', 'date', 'datetime',\n 'image', 'video', 'file',\n 'relation', 'relations',\n 'select', 'array', 'object',\n] as const\n\n/**\n * Shared Zod schema for field definitions.\n * Used by both model_save and normalize extract for full parity.\n *\n * `.strict()` is load-bearing: the default `z.object` *strips* unknown keys, so a\n * typo'd constraint (`requird: true`) used to vanish without a word and the field\n * silently lost the rule its author thought they had declared.\n */\nexport const fieldDefZodSchema: z.ZodType<Record<string, unknown>> = z.record(z.string(), z.object({\n type: z.enum(FIELD_TYPE_ENUM).describe('Field type from the 27-type catalog'),\n required: z.boolean().optional(),\n unique: z.boolean().optional(),\n default: z.unknown().optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n pattern: z.string().optional(),\n options: z.array(z.string()).optional(),\n model: z.union([z.string(), z.array(z.string())]).optional(),\n items: z.union([z.string(), z.lazy(() => z.record(z.string(), z.unknown()))]).optional(),\n fields: z.lazy(() => z.record(z.string(), z.unknown())).optional(),\n accept: z.string().optional(),\n maxSize: z.number().optional(),\n description: z.string().optional(),\n label: z.union([z.string(), z.record(z.string(), z.string())]).optional()\n .describe('Editor label. A string is one label for all locales; an object keyed by locale carries a translation each.'),\n order: z.number().optional()\n .describe('Display position, ascending. Fields without one sort last, alphabetically. Fractional values allowed.'),\n}).strict().refine(\n (f) => {\n if ((f.type === 'relation' || f.type === 'relations') && !f.model) return false\n if (f.type === 'select' && (!f.options || f.options.length === 0)) return false\n return true\n },\n { message: 'relation/relations requires \"model\", select requires non-empty \"options\"' },\n))\n\n// ─── Model Validation (shared between model_save and normalize extract) ───\n\nconst VALID_FIELD_TYPES = new Set<string>(FIELD_TYPE_ENUM)\n\n/** Field types whose value is a path/URL to a media asset. */\nconst MEDIA_FIELD_TYPES = new Set<string>(['image', 'video', 'file'])\n/** Bounds `items`/`fields` nesting; far above any real schema. */\nconst MAX_SCHEMA_DEPTH = 10\n\nexport interface ModelDefinitionIssues {\n /** Block the write. */\n errors: string[]\n /** Surface to the caller; the write proceeds. */\n warnings: string[]\n}\n\ninterface RawFieldDef {\n type?: string\n required?: unknown\n unique?: unknown\n default?: unknown\n min?: unknown\n max?: unknown\n pattern?: unknown\n options?: unknown\n model?: unknown\n items?: unknown\n fields?: unknown\n accept?: unknown\n maxSize?: unknown\n label?: unknown\n order?: unknown\n}\n\n/**\n * Check one field definition, recursing into `fields` and `items`.\n *\n * The governing rule: **do not accept a constraint that will not be enforced.**\n * A constraint that silently does nothing is worse than no constraint, because\n * the author stops looking. So a property declared where it cannot apply is an\n * error, and a property we genuinely cannot enforce says so out loud.\n */\nfunction checkFieldDef(\n raw: unknown,\n path: string,\n modelKind: string,\n errors: string[],\n warnings: string[],\n depth: number,\n): void {\n if (typeof raw !== 'object' || raw === null) {\n errors.push(`Field \"${path}\": must be an object`)\n return\n }\n if (depth > MAX_SCHEMA_DEPTH) {\n errors.push(`Field \"${path}\": exceeds the maximum nesting depth of ${MAX_SCHEMA_DEPTH}`)\n return\n }\n\n const def = raw as RawFieldDef\n const type = def.type\n\n if (!type || !VALID_FIELD_TYPES.has(type)) {\n errors.push(`Field \"${path}\": invalid type \"${type}\"`)\n return\n }\n\n // Presentation. Wrong here is not fatal to a write, but a locale-keyed label\n // whose keys are not locales is the same inversion the vocabulary hits, and\n // it silently resolves to nothing.\n if (def.label !== undefined) {\n if (typeof def.label === 'string') {\n if (def.label.trim() === '') errors.push(`Field \"${path}\": \"label\" is empty`)\n } else if (typeof def.label === 'object' && def.label !== null && !Array.isArray(def.label)) {\n const entries = Object.entries(def.label as Record<string, unknown>)\n if (entries.length === 0) errors.push(`Field \"${path}\": \"label\" has no translations`)\n for (const [locale, value] of entries) {\n if (!LOCALE_PATTERN.test(locale)) {\n errors.push(`Field \"${path}\": \"label\" key \"${locale}\" is not a locale code. A per-locale label nests as { \"en\": \"…\", \"tr\": \"…\" }.`)\n }\n if (typeof value !== 'string' || value.trim() === '') {\n errors.push(`Field \"${path}\": \"label\" for \"${locale}\" must be a non-empty string`)\n }\n }\n } else {\n errors.push(`Field \"${path}\": \"label\" must be a string, or an object keyed by locale`)\n }\n }\n if (def.order !== undefined && (typeof def.order !== 'number' || !Number.isFinite(def.order))) {\n errors.push(`Field \"${path}\": \"order\" must be a finite number`)\n }\n\n if ((type === 'relation' || type === 'relations') && !def.model) {\n errors.push(`Field \"${path}\": ${type} type requires \"model\" property`)\n }\n if (type === 'select' && (!Array.isArray(def.options) || def.options.length === 0)) {\n errors.push(`Field \"${path}\": select type requires non-empty \"options\" array`)\n }\n\n // An object with no shape is a field nothing can validate and no editor can\n // render — it shows as an empty frame. A warning, not an error: it is a\n // legitimate intermediate state while a schema is being designed.\n if (type === 'object' && (!def.fields || typeof def.fields !== 'object' || Object.keys(def.fields as Record<string, unknown>).length === 0)) {\n warnings.push(`Field \"${path}\": \"object\" with no \"fields\" — nothing validates it and no editor can render it. Declare its shape, or use a plain type.`)\n }\n // The reverse direction was never checked, so `options` on a string field was\n // accepted and then silently ignored at validation time.\n if (def.options !== undefined && type !== 'select') {\n errors.push(`Field \"${path}\": \"options\" only applies to select fields — it is ignored on \"${type}\"`)\n }\n if (def.items !== undefined && type !== 'array') {\n errors.push(`Field \"${path}\": \"items\" only applies to array fields — it is ignored on \"${type}\"`)\n }\n if (def.fields !== undefined && type !== 'object') {\n errors.push(`Field \"${path}\": \"fields\" only applies to object fields — it is ignored on \"${type}\"`)\n }\n if (def.accept !== undefined && !MEDIA_FIELD_TYPES.has(type)) {\n errors.push(`Field \"${path}\": \"accept\" only applies to image/video/file fields — it is ignored on \"${type}\"`)\n }\n if (def.maxSize !== undefined && !MEDIA_FIELD_TYPES.has(type)) {\n errors.push(`Field \"${path}\": \"maxSize\" only applies to image/video/file fields — it is ignored on \"${type}\"`)\n }\n\n // A singleton holds one record per locale, so there is nothing for a value to\n // be unique against.\n if (def.unique === true && modelKind === 'singleton') {\n errors.push(`Field \"${path}\": \"unique\" has no meaning on a singleton — the model holds a single record per locale`)\n }\n\n if (typeof def.min === 'number' && typeof def.max === 'number' && def.min > def.max) {\n errors.push(`Field \"${path}\": min (${def.min}) is greater than max (${def.max})`)\n }\n\n // Compile the regex here rather than let it fail once per entry at validation\n // time, where it degrades to a warning and silently disables the constraint.\n if (typeof def.pattern === 'string') {\n try {\n // eslint-disable-next-line no-new\n new RegExp(def.pattern)\n } catch {\n errors.push(`Field \"${path}\": \"pattern\" is not a valid regular expression — /${def.pattern}/`)\n }\n }\n\n if (def.default !== undefined) {\n checkDefaultCoherence(def, type, path, errors)\n }\n\n // `max` on a media field measures the length of the stored path string, not\n // the file — almost certainly not what the author meant.\n if (typeof def.max === 'number' && MEDIA_FIELD_TYPES.has(type)) {\n warnings.push(\n `Field \"${path}\": \"max\" on a ${type} field limits the length of the stored path string, not the file size. Use \"maxSize\" for bytes.`,\n )\n }\n\n // Said plainly rather than accepted in silence: MCP holds a path, never the\n // bytes, so it cannot check this. The provider owns the policy at ingest.\n if (def.maxSize !== undefined && MEDIA_FIELD_TYPES.has(type)) {\n warnings.push(\n `Field \"${path}\": \"maxSize\" is not enforced by MCP — it has no access to the file. Your media provider enforces it when the asset is ingested.`,\n )\n }\n\n if (def.fields !== undefined && typeof def.fields === 'object' && def.fields !== null) {\n for (const [nested, nestedDef] of Object.entries(def.fields as Record<string, unknown>)) {\n if (!/^[a-z][a-z0-9_]*$/.test(nested)) {\n errors.push(`Field \"${path}.${nested}\": invalid name — must be snake_case starting with letter`)\n }\n checkFieldDef(nestedDef, `${path}.${nested}`, modelKind, errors, warnings, depth + 1)\n }\n }\n\n if (typeof def.items === 'string') {\n if (!VALID_FIELD_TYPES.has(def.items)) {\n errors.push(`Field \"${path}.items\": invalid type \"${def.items}\"`)\n }\n } else if (def.items !== undefined) {\n checkFieldDef(def.items, `${path}.items`, modelKind, errors, warnings, depth + 1)\n }\n}\n\n/** A default that its own field would reject is a schema bug, not a content one. */\nfunction checkDefaultCoherence(def: RawFieldDef, type: string, path: string, errors: string[]): void {\n const value = def.default\n const isString = typeof value === 'string'\n const isNumber = typeof value === 'number'\n\n if (type === 'select' && Array.isArray(def.options) && isString && !def.options.includes(value)) {\n errors.push(`Field \"${path}\": default \"${value}\" is not one of its own options [${(def.options as string[]).join(', ')}]`)\n return\n }\n const wantsNumber = ['number', 'integer', 'decimal', 'percent', 'rating'].includes(type)\n const wantsBoolean = type === 'boolean'\n const wantsArray = type === 'array'\n\n if (wantsNumber && !isNumber) {\n errors.push(`Field \"${path}\": default must be a number for type \"${type}\"`)\n } else if (wantsBoolean && typeof value !== 'boolean') {\n errors.push(`Field \"${path}\": default must be a boolean for type \"${type}\"`)\n } else if (wantsArray && !Array.isArray(value)) {\n errors.push(`Field \"${path}\": default must be an array for type \"${type}\"`)\n }\n}\n\n// ─── title_field ───\n\n/** Field names that announce themselves as a title, most explicit first. */\nconst TITLE_NAME_HINTS = ['title', 'name', 'label', 'heading'] as const\n\n/**\n * Preference among displayable types, short scalars first. A title is a label,\n * not a body: given both `question: string` and `answer: text`, the string wins.\n * Without this, \"first required text field\" resolves alphabetically and a FAQ\n * model gets titled by its answers.\n */\nconst TITLE_TYPE_PRIORITY: readonly FieldType[] = [\n 'string', 'slug', 'email', 'url', 'code', 'text', 'markdown', 'richtext',\n]\n\nexport interface TitleFieldPick {\n field: string\n /** Which rule chose it — surfaced to the user so an inferred title can be overruled. */\n rule: 'dictionary' | 'name-match' | 'required-displayable' | 'displayable'\n}\n\ninterface TitleCandidate {\n field: string\n type: FieldType\n required: boolean\n}\n\n/** Fields that could carry a title at all. Everything else is out of the running. */\nfunction titleCandidates(fields?: Record<string, unknown>): TitleCandidate[] {\n if (!fields) return []\n const out: TitleCandidate[] = []\n for (const [field, raw] of Object.entries(fields)) {\n const def = raw as { type?: unknown; required?: unknown } | null\n const type = def?.type\n if (typeof type !== 'string' || !isTitleFieldType(type as FieldType)) continue\n out.push({ field, type: type as FieldType, required: def?.required === true })\n }\n return out\n}\n\nfunction byTypeThenName(a: TitleCandidate, b: TitleCandidate): number {\n const byType = TITLE_TYPE_PRIORITY.indexOf(a.type) - TITLE_TYPE_PRIORITY.indexOf(b.type)\n return byType !== 0 ? byType : a.field.localeCompare(b.field, 'en')\n}\n\n/**\n * How strongly a field name reads as a title. Exact matches outrank snake_case\n * token matches, so `name` beats `brand_name`, and `filename` matches nothing —\n * it tokenizes to `[\"filename\"]`, not `[\"file\", \"name\"]`.\n */\nfunction titleNameRank(field: string): number {\n const exact = (TITLE_NAME_HINTS as readonly string[]).indexOf(field)\n if (exact !== -1) return exact\n\n const tokens = field.split('_')\n const token = TITLE_NAME_HINTS.findIndex(hint => tokens.includes(hint))\n return token === -1 ? Number.POSITIVE_INFINITY : TITLE_NAME_HINTS.length + token\n}\n\n/**\n * Pick the field a model should title its entries by.\n *\n * Migration aid only — it exists to backfill models authored before `title_field`\n * was required, and `contentrain validate --fix` is its one caller. New models\n * declare the field; nothing here runs on the write path.\n *\n * Every rung filters by `isTitleFieldType` first. That filter is the whole point:\n * an unfiltered name match hands the title to a field called `name` that happens\n * to be typed `icon`, which is the exact bug this contract replaces.\n *\n * Returns `null` when no field can render as a title. That is a real answer, not a\n * failure — guessing `image` or `relation` here would re-create the bug, so the\n * validation error stands and a human picks.\n */\nexport function inferTitleField(kind: string, fields?: Record<string, unknown>): TitleFieldPick | null {\n // A dictionary has no fields to point at — its key is the title.\n if (kind === 'dictionary') return { field: DICTIONARY_TITLE_FIELD, rule: 'dictionary' }\n\n const candidates = titleCandidates(fields)\n if (candidates.length === 0) return null\n\n const named = candidates.filter(c => Number.isFinite(titleNameRank(c.field)))\n if (named.length > 0) {\n const best = named.toSorted((a, b) => {\n const byName = titleNameRank(a.field) - titleNameRank(b.field)\n return byName !== 0 ? byName : byTypeThenName(a, b)\n })[0]!\n return { field: best.field, rule: 'name-match' }\n }\n\n const required = candidates.filter(c => c.required)\n if (required.length > 0) {\n return { field: required.toSorted(byTypeThenName)[0]!.field, rule: 'required-displayable' }\n }\n\n return { field: candidates.toSorted(byTypeThenName)[0]!.field, rule: 'displayable' }\n}\n\n/**\n * The `title_field` rule table.\n *\n * Extracted so `validateModelDefinition` (write path) and the project validator\n * (read path) report the same wording from one place, rather than one of them\n * sniffing the other's strings.\n *\n * Chained so a model gets one title_field error, not a cascade of five.\n */\nexport function titleFieldIssues(\n input: { kind: string; title_field?: unknown; fields?: Record<string, unknown> },\n): ModelDefinitionIssues {\n const errors: string[] = []\n const warnings: string[] = []\n const titleField = input.title_field\n\n if (titleField === undefined || titleField === null || titleField === '') {\n errors.push('Missing \"title_field\". Every model must name the field shown as its title. Dictionary models use \"key\".')\n } else if (typeof titleField !== 'string') {\n errors.push(`Invalid \"title_field\": must be a string, got ${typeof titleField}.`)\n } else if (input.kind === 'dictionary') {\n if (titleField !== DICTIONARY_TITLE_FIELD) {\n errors.push(`Dictionary models must use title_field: \"${DICTIONARY_TITLE_FIELD}\". Dictionaries have no fields — the key is the title. Got \"${titleField}\".`)\n }\n } else if (!input.fields || Object.keys(input.fields).length === 0) {\n errors.push(`Invalid \"title_field\": \"${titleField}\" cannot resolve — the model declares no fields.`)\n } else if (!(titleField in input.fields)) {\n // A non-dictionary model may legitimately own a field named \"key\" — the\n // sentinel only collides where there are no fields at all.\n errors.push(\n `Invalid \"title_field\": field \"${titleField}\" is not defined in fields.`\n + (titleField === DICTIONARY_TITLE_FIELD ? ` \"${DICTIONARY_TITLE_FIELD}\" is reserved for dictionary models.` : ''),\n )\n } else {\n const def = input.fields[titleField] as { type?: unknown; required?: unknown } | undefined\n const type = def?.type\n if (typeof type === 'string' && !isTitleFieldType(type as FieldType)) {\n errors.push(`Invalid \"title_field\": field \"${titleField}\" has type \"${type}\" — a title must be one of: ${TITLE_FIELD_TYPES.join(', ')}.`)\n } else if (def?.required !== true) {\n warnings.push(`\"title_field\" points at optional field \"${titleField}\" — entries may render with an empty title. Consider required: true.`)\n }\n // A non-string `type` falls through: the per-field loop already reports it,\n // and repeating it here would double-count one mistake.\n }\n\n return { errors, warnings }\n}\n\n/**\n * Validate a model definition before writing.\n * Used by both the model_save tool and normalize extract.\n */\nexport function validateModelDefinition(\n // `title_field` is `unknown`, not `string?`: a model read back off disk is an\n // unvalidated cast, so the runtime check has to see a value the type system\n // already believes is a string.\n input: { id: string; kind: string; title_field?: unknown; fields?: Record<string, unknown> },\n): ModelDefinitionIssues {\n const errors: string[] = []\n const warnings: string[] = []\n\n // ID format: kebab-case\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(input.id)) {\n errors.push(`Invalid model ID \"${input.id}\": must be kebab-case`)\n }\n\n // Dictionary models cannot have fields\n if (input.kind === 'dictionary' && input.fields && Object.keys(input.fields).length > 0) {\n errors.push('Dictionary models cannot have fields. Dictionaries store flat key-value pairs.')\n }\n\n // Reported above the per-field loop: a broken title_field explains the model,\n // the field errors only explain one field.\n const titleIssues = titleFieldIssues(input)\n errors.push(...titleIssues.errors)\n warnings.push(...titleIssues.warnings)\n\n if (input.fields) {\n for (const [fieldName, fieldDef] of Object.entries(input.fields)) {\n if (!/^[a-z][a-z0-9_]*$/.test(fieldName)) {\n errors.push(`Field \"${fieldName}\": invalid name — must be snake_case starting with letter`)\n }\n checkFieldDef(fieldDef, fieldName, input.kind, errors, warnings, 0)\n }\n }\n\n return { errors, warnings }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAeA,IAAa,cAAb,MAA+C;CAC7C,YAAY,aAAqC;AAArB,OAAA,cAAA;;CAE5B,MAAM,SAAS,MAAc,MAAgC;AAC3D,SAAO,SAAS,QAAQ,KAAK,aAAa,KAAK,EAAE,QAAQ;;CAG3D,MAAM,cAAc,MAAc,MAAkC;AAClE,MAAI;AACF,UAAO,MAAM,QAAQ,QAAQ,KAAK,aAAa,KAAK,CAAC;UAC/C;AACN,UAAO,EAAE;;;CAIb,MAAM,WAAW,MAAc,MAAiC;AAC9D,MAAI;AACF,SAAM,OAAO,QAAQ,KAAK,aAAa,KAAK,CAAC;AAC7C,UAAO;UACD;AACN,UAAO;;;;;;;ACpBb,MAAM,oBAAoB;AAc1B,SAAgB,kBAAkB,aAAqB,OAAiC;AACtF,KAAI,MAAM,aACR,QAAO,KAAK,aAAa,MAAM,aAAa;AAE9C,QAAO,KAAK,eAAe,YAAY,EAAE,WAAW,MAAM,QAAQ,MAAM,GAAG;;AAG7E,SAAgB,sBAAsB,OAA4C;AAChF,QAAO,MAAM,mBAAmB;;;AAIlC,SAAgB,oBAAoB,KAAa,OAAyB,QAAwB;AAEhG,KAAI,CAAC,MAAM,KAAM,QAAO,KAAK,KAAK,YAAY;AAE9C,SAAQ,sBAAsB,MAAM,EAApC;EACE,KAAK,SAAU,QAAO,KAAK,KAAK,GAAG,MAAM,GAAG,GAAG,OAAO,OAAO;EAC7D,KAAK,YAAa,QAAO,KAAK,KAAK,QAAQ,GAAG,MAAM,GAAG,OAAO;EAC9D,KAAK,OAAQ,QAAO,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO;EAEjD,QAAS,QAAO,KAAK,KAAK,GAAG,OAAO,OAAO;;;;AAK/C,SAAgB,kBAAkB,KAAa,OAA0D,QAAgB,MAAsB;AAE7I,KAAI,CAAC,MAAM,KAAM,QAAO,KAAK,KAAK,GAAG,KAAK,KAAK;AAE/C,SAAQ,sBAAsB,MAAM,EAApC;EACE,KAAK,SAAU,QAAO,KAAK,KAAK,GAAG,KAAK,GAAG,OAAO,KAAK;EACvD,KAAK,YAAa,QAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,KAAK;EACxD,KAAK,OAAQ,QAAO,KAAK,KAAK,GAAG,KAAK,KAAK;EAE3C,QAAS,QAAO,KAAK,KAAK,MAAM,GAAG,OAAO,KAAK;;;AAwCnD,eAAsB,aACpB,aACA,OACA,SACA,QACA,YACwB;CACxB,MAAM,UAAyB,EAAE;CACjC,MAAM,gBAAgB,OAAO,QAAQ;AAErC,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,SAAS,MAAM,UAAU;EAG/B,MAAM,YAAYA,iBAAe,QAAQ,OAAO;AAChD,MAAI,UAAW,OAAM,IAAI,MAAM,UAAU;AAGzC,MAAI,MAAM,IAAI;GACZ,MAAM,QAAQC,kBAAgB,MAAM,GAAG;AACvC,OAAI,MAAO,OAAM,IAAI,MAAM,MAAM;;AAInC,MAAI,MAAM,MAAM;GACd,MAAM,UAAUC,eAAa,MAAM,KAAK;AACxC,OAAI,QAAS,OAAM,IAAI,MAAM,QAAQ;;AAGvC,UAAQ,MAAM,MAAd;GACE,KAAK,aAAa;AAEhB,UAAM,UADW,oBAAoB,kBAAkB,aAAa,MAAM,EAAE,OAAO,OAAO,EAChE,MAAM,KAAK;IACrC,MAAM,WAAW,MAAM,SAAS,aAAa,OAAO;KAAE;KAAQ;KAAe,CAAC;AAC9E,UAAM,UAAU,aAAa,OAAO;KAAE;KAAQ;KAAe,EAAE,eAAe,YAAY,KAAA,GAAW,MAAM,KAAK,CAAC;AACjH,YAAQ,KAAK;KAAE,QAAQ;KAAW;KAAQ,CAAC;AAC3C;;GAGF,KAAK,cAAc;IACjB,MAAM,QAAQ,CAAC,MAAM;IACrB,MAAM,KAAK,MAAM,MAAM,iBAAiB;IACxC,MAAM,WAAW,oBAAoB,kBAAkB,aAAa,MAAM,EAAE,OAAO,OAAO;IAC1F,MAAM,WAAW,MAAM,SAAkD,SAAS,IAAI,EAAE;IAExF,MAAM,SAAiC,SAAS,EAAE,MAAM,YAAa,YAAY;AACjF,aAAS,MAAM,MAAM;IAGrB,MAAM,SAAkD,EAAE;AAC1D,SAAK,MAAM,OAAO,OAAO,KAAK,SAAS,CAAC,UAAU,CAChD,QAAO,OAAO,SAAS;AAGzB,UAAM,UAAU,UAAU,OAAO;IACjC,MAAM,cAAc,MAAM,SAAS,aAAa,OAAO;KAAE;KAAQ;KAAe,CAAC;AACjF,UAAM,UAAU,aAAa,OAAO;KAAE;KAAQ,SAAS;KAAI;KAAe,EAAE,eAAe,cAAc,KAAK,MAAM,KAAK,CAAC;AAC1H,YAAQ,KAAK;KAAE;KAAQ;KAAI;KAAQ,CAAC;AACpC;;GAGF,KAAK,YAAY;IACf,MAAM,OAAO,MAAM,QAAQ,MAAM,KAAK;AACtC,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,kCAAkC;IAC7D,MAAM,UAAUA,eAAa,KAAK;AAClC,QAAI,QAAS,OAAM,IAAI,MAAM,QAAQ;IAErC,MAAM,aAAa,EAAE,GAAG,MAAM,MAAM;IACpC,MAAM,WAAW,UAAU;IAC3B,MAAM,eAAgB,WAAW,WAAkC;AACnE,WAAO,WAAW;AAClB,QAAI,CAAC,WAAW,QAAS,YAAW,UAAU;IAG9C,MAAM,UAAU,kBAAkB,kBAAkB,aAAa,MAAM,EAAE,OAAO,QAAQ,KAAK;IAC7F,MAAM,cAAc,MAAM,SAAS,QAAQ;IAC3C,MAAM,SAAgC,cAAc,YAAY;IAKhE,MAAM,cAAc,cAAc,yBAAyB,YAAY,GAAG;AAK1E,UAAM,UAAU,SADE,6BAHH;KAAE,GAAG,aAAa;KAAa,GAAG;KAAY,EACzC,WAAW,eAAgB,aAAa,QAAQ,GAED,CAChC;IACnC,MAAM,WAAW,MAAM,SAAS,aAAa,OAAO;KAAE;KAAQ;KAAM;KAAe,CAAC;AACpF,UAAM,UAAU,aAAa,OAAO;KAAE;KAAQ;KAAM;KAAe,EAAE,eAAe,YAAY,KAAA,GAAW,MAAM,KAAK,CAAC;AACvH,YAAQ,KAAK;KAAE;KAAQ;KAAM;KAAQ,CAAC;AACtC;;GAGF,KAAK,cAAc;IACjB,MAAM,WAAW,oBAAoB,kBAAkB,aAAa,MAAM,EAAE,OAAO,OAAO;IAC1F,MAAM,WAAW,MAAM,SAAiC,SAAS,IAAI,EAAE;IAEvE,MAAM,aAAuB,EAAE;IAI/B,MAAM,WAAW,MAAM;IACvB,MAAM,WAAW,OAAO,KAAK,SAAS,CAAC,QACrC,MAAK,KAAK,YAAY,SAAS,OAAO,SAAS,GAChD;AACD,QAAI,SAAS,SAAS,GAAG;KACvB,MAAM,QAAQ,SAAS,MAAM,GAAG,kBAAkB;KAClD,MAAM,SAAS,MAAM,KAAI,MAAK,IAAI,EAAE,MAAM,SAAS,GAAG,OAAO,SAAS,GAAG,GAAG,CAAC,KAAK,KAAK;KACvF,MAAM,OAAO,SAAS,SAAS,MAAM,SAAS,SAAS,SAAS,SAAS,MAAM,OAAO,SAAS;AAC/F,gBAAW,KACT,eAAe,MAAM,GAAG,KAAK,OAAO,cAAc,SAAS,OAAO,uBAAuB,SAAS,KAAK,GACxG;;IAEH,MAAM,6BAAa,IAAI,KAAqB;AAC5C,SAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,SAAS,CAC3C,YAAW,IAAI,GAAG,EAAE;AAEtB,SAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,MAAM,KAA+B,EAAE;AACrF,SAAI,UAAU,SAAU;KACxB,MAAM,cAAc,WAAW,IAAI,SAAmB;AACtD,SAAI,eAAe,gBAAgB,OACjC,YAAW,KACT,UAAU,SAAS,2BAA2B,YAAY,2CAA2C,OAAO,IAC7G;;AAKL,QAAI,cAAc,OAAO,KAAK,WAAW,MAAM,CAAC,SAAS,EACvD,MAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,MAAM,KAA+B,EAAE;AACrF,SAAI,UAAU,SAAU;AACxB,UAAK,MAAM,GAAG,iBAAiB,OAAO,QAAQ,WAAW,MAAM,CAC7D,KAAI,OAAO,OAAO,aAAa,CAAC,SAAS,SAAmB,EAAE;AAC5D,iBAAW,KACT,UAAU,SAAS,sEACpB;AACD;;;AAOR,UAAM,UAAU,UADD;KAAE,GAAG;KAAU,GAAG,MAAM;KAAgC,CACtC;IACjC,MAAM,WAAW,MAAM,SAAS,aAAa,OAAO;KAAE;KAAQ;KAAe,CAAC;AAC9E,UAAM,UAAU,aAAa,OAAO;KAAE;KAAQ;KAAe,EAAE,eAAe,YAAY,KAAA,GAAW,MAAM,KAAK,CAAC;AACjH,YAAQ,KAAK;KAAE,QAAQ;KAAW;KAAQ,GAAI,WAAW,SAAS,IAAI,EAAE,YAAY,GAAG,EAAE;KAAG,CAAC;AAC7F;;;;AAKN,QAAO;;AAKT,eAAsB,cACpB,aACA,OACA,MACmB;AAMnB,KAAI,CAAC,MAAM,QAAQ,KAAK,OACtB,OAAM,IAAI,MACR,UAAU,MAAM,GAAG,kOAGpB;CAGH,MAAM,UAAoB,EAAE;CAC5B,MAAM,OAAO,kBAAkB,aAAa,MAAM;AAElD,SAAQ,MAAM,MAAd;EACE,KAAK,cAAc;AACjB,OAAI,CAAC,KAAK,GAAI,OAAM,IAAI,MAAM,yCAAyC;GACvE,MAAM,UAAU,KAAK,SACjB,CAAC,KAAK,OAAO,IACZ,MAAM,QAAQ,KAAK,EAAE,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC,CAAC,KAAI,MAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,CAAC;AAEvH,QAAK,MAAM,OAAO,SAAS;IACzB,MAAM,WAAW,oBAAoB,MAAM,OAAO,IAAI;IACtD,MAAM,OAAO,MAAM,SAAkC,SAAS;AAC9D,QAAI,QAAQ,KAAK,MAAM,MAAM;AAC3B,YAAO,KAAK,KAAK;AACjB,WAAM,UAAU,UAAU,KAAK;AAC/B,aAAQ,KAAK,WAAW,MAAM,OAAO,GAAG,MAAM,GAAG,GAAG,IAAI,QAAQ,KAAK,KAAK;;;AAI9E,QAAK,MAAM,OAAO,QAChB,OAAM,WAAW,aAAa,OAAO;IAAE,QAAQ;IAAK,SAAS,KAAK;IAAI,eAAe,KAAK;IAAe,CAAC;AAE5G;;EAGF,KAAK,YAAY;AACf,OAAI,CAAC,KAAK,KAAM,OAAM,IAAI,MAAM,kCAAkC;GAClE,MAAM,aAAaA,eAAa,KAAK,KAAK;AAC1C,OAAI,WAAY,OAAM,IAAI,MAAM,WAAW;GAE3C,MAAM,WAAW,sBAAsB,MAAM;AAC7C,OAAI,CAAC,MAAM,KAET,OAAM,GAAG,KAAK,MAAM,GAAG,KAAK,KAAK,KAAK,EAAE,EAAE,OAAO,MAAM,CAAC;YAC/C,aAAa,OAEtB,OAAM,GAAG,KAAK,MAAM,KAAK,KAAK,EAAE;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;YACxD,KAAK,OAGd,OAAM,GADW,kBAAkB,MAAM,OAAO,KAAK,QAAQ,KAAK,KAAK,EACpD,EAAE,OAAO,MAAM,CAAC;QAC9B;IAEL,MAAM,QAAQ,MAAM,QAAQ,aAAa,cAAc,OAAO,KAAK;AACnE,SAAK,MAAM,KAAK,MACd,KAAI,aAAa,YAAY,EAAE,WAAW,GAAG,KAAK,KAAK,GAAG,IAAI,EAAE,SAAS,MAAM,CAC7E,OAAM,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE,OAAO,MAAM,CAAC;aAC/B,aAAa,YAEtB,OAAM,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,KAAK,KAAK,EAAE,EAAE,OAAO,MAAM,CAAC;aAClD,aAAa;SAClB,MAAM,GAAG,KAAK,KAAK,KAAM,OAAM,GAAG,KAAK,MAAM,EAAE,EAAE,EAAE,OAAO,MAAM,CAAC;;;AAI3E,WAAQ,KAAK,GAAG,MAAM,gBAAgB,WAAW,MAAM,OAAO,GAAG,MAAM,KAAK,GAAG,KAAK,OAAO;AAE3F,SAAM,WAAW,aAAa,OAAO;IAAE,MAAM,KAAK;IAAM,QAAQ,KAAK;IAAQ,eAAe,KAAK;IAAe,CAAC;AACjH;;EAGF,KAAK,aAAa;AAChB,OAAI,MAAM,QAAQ,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,0DAA0D;GAC1G,MAAM,SAAS,KAAK,UAAU;AAE9B,SAAM,GADW,oBAAoB,MAAM,OAAO,OAAO,EACtC,EAAE,OAAO,MAAM,CAAC;AACnC,WAAQ,KAAK,MAAM,OACf,WAAW,MAAM,OAAO,GAAG,MAAM,GAAG,GAAG,OAAO,SAC9C,WAAW,MAAM,OAAO,GAAG,MAAM,GAAG,YAAY;AACpD,SAAM,WAAW,aAAa,OAAO;IAAE,QAAQ,MAAM,OAAO,SAAS,KAAA;IAAW,eAAe,KAAK;IAAe,CAAC;AACpH;;EAGF,KAAK,cAAc;AACjB,OAAI,MAAM,QAAQ,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,2DAA2D;GAC3G,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,WAAW,oBAAoB,MAAM,OAAO,OAAO;AAEzD,OAAI,KAAK,MAAM,QAAQ;IAErB,MAAM,WAAW,MAAM,SAAiC,SAAS,IAAI,EAAE;IACvE,MAAM,WAAqB,EAAE;AAC7B,SAAK,MAAM,OAAO,KAAK,KACrB,KAAI,OAAO,SACT,QAAO,SAAS;QAEhB,UAAS,KAAK,IAAI;AAGtB,QAAI,SAAS,SAAS,EACpB,OAAM,IAAI,MAAM,eAAe,MAAM,GAAG,KAAK,OAAO,uBAAuB,SAAS,KAAK,KAAK,CAAC,GAAG;AAEpG,UAAM,UAAU,UAAU,SAAS;AACnC,YAAQ,KAAK,GAAG,KAAK,KAAK,KAAI,MAAK,GAAG,MAAM,GAAG,GAAG,OAAO,GAAG,IAAI,CAAC;UAC5D;AAEL,UAAM,GAAG,UAAU,EAAE,OAAO,MAAM,CAAC;AACnC,YAAQ,KAAK,MAAM,OACf,WAAW,MAAM,OAAO,GAAG,MAAM,GAAG,GAAG,OAAO,SAC9C,WAAW,MAAM,OAAO,GAAG,MAAM,GAAG,YAAY;AACpD,UAAM,WAAW,aAAa,OAAO;KAAE,QAAQ,MAAM,OAAO,SAAS,KAAA;KAAW,eAAe,KAAK;KAAe,CAAC;;AAEtH;;;AAIJ,QAAO;;AAgCT,eAAsB,YACpB,OACA,OACA,MACA,QACkB;AAClB,KAAI,OAAO,UAAU,SACnB,QAAO,qBAAqB,OAAO,OAAO,MAAM,OAAO;AAEzD,QAAO,iBAAiB,OAAO,OAAO,MAAM,OAAO;;AAGrD,eAAe,iBACb,aACA,OACA,MACA,QACkB;CAClB,MAAM,OAAO,kBAAkB,aAAa,MAAM;CAClD,MAAM,SAAS,KAAK,UAAU,OAAO,QAAQ;AAE7C,SAAQ,MAAM,MAAd;EACE,KAAK,YAEH,QAAO;GAAE,MAAM;GAAa,MADf,MAAM,SAAkC,oBAAoB,MAAM,OAAO,OAAO,CAAC,IACpD,EAAE;GAAE;GAAQ;EAGxD,KAAK,cAAc;GACjB,MAAM,OAAO,MAAM,SAAkD,oBAAoB,MAAM,OAAO,OAAO,CAAC,IAAI,EAAE;GACpH,IAAI,UAA0C,OAAO,QAAQ,KAAK,CAAC,KAAK,CAAC,IAAI,YAAY;IACvF,MAAM,QAAiC,EAAE,IAAI;AAC7C,WAAO,OAAO,OAAO,OAAO;AAC5B,WAAO;KACP;AAGF,OAAI,KAAK,OACP,WAAU,QAAQ,QAAO,UAAS;AAChC,SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,OAAQ,CACrD,KAAI,MAAM,SAAS,MAAO,QAAO;AAEnC,WAAO;KACP;GAGJ,MAAM,QAAQ,QAAQ;GAGtB,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,aAAU,QAAQ,MAAM,QAAQ,SAAS,MAAM;AAG/C,OAAI,KAAK,WAAW,MAAM,OACxB,WAAU,MAAM,iBAAiB,aAAa,OAAO,SAAS,OAAO;AAGvE,UAAO;IAAE,MAAM;IAAc,MAAM;IAAS;IAAO;IAAQ;IAAQ;IAAO;;EAG5E,KAAK,YAAY;GACf,MAAM,UAA2B,EAAE;GACnC,MAAM,WAAW,sBAAsB,MAAM;AAE7C,OAAI,CAAC,MAAM,MAAM;IAEf,MAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,aAAQ,KAAK;MAAE;MAAM;MAAa;MAAM,CAAC;;cAElC,aAAa,QAAQ;IAE9B,MAAM,WAAW,MAAM,QAAQ,KAAK;AACpC,SAAK,MAAM,QAAQ,UAAU;KAC3B,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC;AAC5D,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,aAAQ,KAAK;MAAE;MAAM;MAAa;MAAM,CAAC;;cAElC,aAAa,UAAU;IAEhC,MAAM,QAAQ,MAAM,QAAQ,KAAK;IACjC,MAAM,SAAS,IAAI,OAAO;AAC1B,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,OAAO,CAAE;KACzB,MAAM,OAAO,EAAE,MAAM,GAAG,CAAC,OAAO,OAAO;KACvC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,aAAQ,KAAK;MAAE;MAAM;MAAa;MAAM,CAAC;;cAElC,aAAa,aAAa;IAEnC,MAAM,YAAY,KAAK,MAAM,OAAO;IACpC,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,WAAW,EAAE,CAAC;AAC9C,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,aAAQ,KAAK;MAAE;MAAM;MAAa;MAAM,CAAC;;UAEtC;IAEL,MAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,aAAQ,KAAK;MAAE;MAAM;MAAa;MAAM,CAAC;;;GAI7C,MAAM,QAAQ,QAAQ;GACtB,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,QAAQ,KAAK,SAAS,QAAQ;AAGpC,UAAO;IAAE,MAAM;IAAY,MAFb,QAAQ,MAAM,QAAQ,SAAS,MAAM;IAEX;IAAO;IAAQ;IAAQ;IAAO;;EAGxE,KAAK,cAAc;GACjB,MAAM,OAAO,MAAM,SAAiC,oBAAoB,MAAM,OAAO,OAAO,CAAC,IAAI,EAAE;AACnG,UAAO;IAAE,MAAM;IAAc;IAAM,YAAY,OAAO,KAAK,KAAK,CAAC;IAAQ;IAAQ;;;;AAKvF,eAAeC,uBAAwB,QAAoB,MAAiC;AAC1F,KAAI;AACF,SAAO,KAAK,MAAM,MAAM,OAAO,SAAS,KAAK,CAAC;SACxC;AACN,SAAO;;;AAIX,eAAe,qBAAqB,QAAoB,MAAsC;AAC5F,KAAI;AACF,SAAO,MAAM,OAAO,SAAS,KAAK;SAC5B;AACN,SAAO;;;AAIX,eAAe,qBACb,QACA,OACA,MACA,QACkB;AAClB,KAAI,KAAK,QACP,OAAM,IAAI,MACR,uJAED;CAGH,MAAM,OAAO,eAAe,MAAM;CAClC,MAAM,SAAS,KAAK,UAAU,OAAO,QAAQ;AAE7C,SAAQ,MAAM,MAAd;EACE,KAAK,YAEH,QAAO;GAAE,MAAM;GAAa,MADf,MAAMA,uBAA8C,QAAQ,gBAAgB,OAAO,OAAO,CAAC,IAC9D,EAAE;GAAE;GAAQ;EAGxD,KAAK,cAAc;GACjB,MAAM,OAAO,MAAMA,uBACjB,QACA,gBAAgB,OAAO,OAAO,CAC/B,IAAI,EAAE;GACP,IAAI,UAA0C,OAAO,QAAQ,KAAK,CAAC,KAAK,CAAC,IAAI,YAAY;IACvF,MAAM,QAAiC,EAAE,IAAI;AAC7C,WAAO,OAAO,OAAO,OAAO;AAC5B,WAAO;KACP;AAEF,OAAI,KAAK,OACP,WAAU,QAAQ,QAAO,UAAS;AAChC,SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,OAAQ,CACrD,KAAI,MAAM,SAAS,MAAO,QAAO;AAEnC,WAAO;KACP;GAGJ,MAAM,QAAQ,QAAQ;GACtB,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,aAAU,QAAQ,MAAM,QAAQ,SAAS,MAAM;AAE/C,UAAO;IAAE,MAAM;IAAc,MAAM;IAAS;IAAO;IAAQ;IAAQ;IAAO;;EAG5E,KAAK,YAAY;GACf,MAAM,UAA2B,EAAE;GACnC,MAAM,WAAW,sBAAsB,MAAM;GAE7C,MAAM,eAAe,OAAO,SAAiB,SAAgC;IAC3E,MAAM,MAAM,MAAM,qBAAqB,QAAQ,QAAQ;AACvD,QAAI,CAAC,IAAK;IACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,YAAQ,KAAK;KAAE;KAAM;KAAa;KAAM,CAAC;;AAG3C,OAAI,CAAC,MAAM,MAAM;IACf,MAAM,QAAQ,MAAM,OAAO,cAAc,KAAK;AAC9C,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;AACxB,WAAM,aAAa,iBAAiB,OAAO,QAAQ,EAAE,QAAQ,UAAU,GAAG,CAAC,EAAE,EAAE,QAAQ,UAAU,GAAG,CAAC;;cAE9F,aAAa,QAAQ;IAC9B,MAAM,WAAW,MAAM,OAAO,cAAc,KAAK;AACjD,SAAK,MAAM,QAAQ,SACjB,OAAM,aAAa,iBAAiB,OAAO,QAAQ,KAAK,EAAE,KAAK;cAExD,aAAa,UAAU;IAChC,MAAM,QAAQ,MAAM,OAAO,cAAc,KAAK;IAC9C,MAAM,SAAS,IAAI,OAAO;AAC1B,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,OAAO,CAAE;KACzB,MAAM,OAAO,EAAE,MAAM,GAAG,CAAC,OAAO,OAAO;AACvC,WAAM,aAAa,iBAAiB,OAAO,QAAQ,KAAK,EAAE,KAAK;;cAExD,aAAa,aAAa;IACnC,MAAM,QAAQ,MAAM,OAAO,cAAc,GAAG,KAAK,GAAG,SAAS;AAC7D,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,UAAU,GAAG;AACpC,WAAM,aAAa,iBAAiB,OAAO,QAAQ,KAAK,EAAE,KAAK;;UAE5D;IACL,MAAM,QAAQ,MAAM,OAAO,cAAc,KAAK;AAC9C,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,UAAU,GAAG;AACpC,WAAM,aAAa,iBAAiB,OAAO,QAAQ,KAAK,EAAE,KAAK;;;GAInE,MAAM,QAAQ,QAAQ;GACtB,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,QAAQ,KAAK,SAAS,QAAQ;AAGpC,UAAO;IAAE,MAAM;IAAY,MAFb,QAAQ,MAAM,QAAQ,SAAS,MAAM;IAEX;IAAO;IAAQ;IAAQ;IAAO;;EAGxE,KAAK,cAAc;GACjB,MAAM,OAAO,MAAMA,uBAA6C,QAAQ,gBAAgB,OAAO,OAAO,CAAC,IAAI,EAAE;AAC7G,UAAO;IAAE,MAAM;IAAc;IAAM,YAAY,OAAO,KAAK,KAAK,CAAC;IAAQ;IAAQ;;;;AAOvF,eAAsB,YACpB,aACA,OACA,MACkB;CAClB,MAAM,OAAO,kBAAkB,aAAa,MAAM;AAElD,SAAQ,MAAM,MAAd;EACE,KAAK,YACH,QAAO,SAAkC,oBAAoB,MAAM,OAAO,KAAK,OAAO,CAAC;EAEzF,KAAK,cAAc;AACjB,OAAI,CAAC,KAAK,QAAS,QAAO;GAC1B,MAAM,OAAO,MAAM,SAAkD,oBAAoB,MAAM,OAAO,KAAK,OAAO,CAAC;AACnH,UAAO,OAAO,KAAK,WAAW;IAAE,IAAI,KAAK;IAAS,GAAG,KAAK,KAAK;IAAU,GAAG;;EAG9E,KAAK,YAAY;AACf,OAAI,CAAC,KAAK,KAAM,QAAO;GACvB,MAAM,MAAM,MAAM,SAAS,kBAAkB,MAAM,OAAO,KAAK,QAAQ,KAAK,KAAK,CAAC;AAClF,OAAI,CAAC,IAAK,QAAO;GACjB,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,UAAO;IAAE,MAAM,KAAK;IAAM,GAAG;IAAa;IAAM;;EAGlD,KAAK,aACH,QAAO,SAAiC,oBAAoB,MAAM,OAAO,KAAK,OAAO,CAAC;;;AAM5F,eAAe,iBACb,aACA,OACA,SACA,QACyC;AACzC,KAAI,CAAC,MAAM,OAAQ,QAAO;CAE1B,MAAM,iBAAkF,EAAE;AAC1F,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,OAAO,CACtD,KAAI,MAAM,SAAS,cAAc,MAAM,SAAS,aAAa;EAC3D,MAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,GAAG,MAAM,QAAQ,MAAM,QAAQ,CAAC,MAAM,MAAM,GAAG,EAAE;AAC3F,iBAAe,KAAK;GAAE;GAAM,cAAc;GAAS,OAAO,MAAM,SAAS;GAAa,CAAC;;AAI3F,KAAI,eAAe,WAAW,EAAG,QAAO;CAGxC,MAAM,cAAuE,EAAE;CAC/E,MAAM,UAAU,IAAI,IAAY,CAAC,MAAM,GAAG,CAAC;AAE3C,MAAK,MAAM,MAAM,eACf,MAAK,MAAM,iBAAiB,GAAG,cAAc;AAC3C,MAAI,YAAY,kBAAkB,QAAQ,IAAI,cAAc,CAAE;AAC9D,UAAQ,IAAI,cAAc;EAE1B,MAAM,cAAc,MAAM,UAAU,aAAa,cAAc;AAC/D,MAAI,CAAC,YAAa;AAElB,MAAI,YAAY,SAAS,aAIvB,aAAY,iBAHO,MAAM,SACvB,oBAAoB,kBAAkB,aAAa,YAAY,EAAE,aAAa,OAAO,CACtF,IAAI,EAAE;WAEE,YAAY,SAAS,YAAY;GAE1C,MAAM,WAAoD,EAAE;GAC5D,MAAM,OAAO,kBAAkB,aAAa,YAAY;GACxD,MAAM,WAAW,sBAAsB,YAAY;AAEnD,OAAI,CAAC,YAAY,MAAM;IACrB,MAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,cAAS,QAAQ;MAAE;MAAM,GAAG;MAAa;MAAM;;cAExC,aAAa,QAAQ;IAC9B,MAAM,WAAW,MAAM,QAAQ,KAAK;AACpC,SAAK,MAAM,QAAQ,UAAU;KAC3B,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC;AAC5D,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,cAAS,QAAQ;MAAE;MAAM,GAAG;MAAa;MAAM;;cAExC,aAAa,UAAU;IAChC,MAAM,QAAQ,MAAM,QAAQ,KAAK;IACjC,MAAM,SAAS,IAAI,OAAO;AAC1B,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,OAAO,CAAE;KACzB,MAAM,OAAO,EAAE,MAAM,GAAG,CAAC,OAAO,OAAO;KACvC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,cAAS,QAAQ;MAAE;MAAM,GAAG;MAAa;MAAM;;cAExC,aAAa,aAAa;IACnC,MAAM,YAAY,KAAK,MAAM,OAAO;IACpC,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,WAAW,EAAE,CAAC;AAC9C,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,cAAS,QAAQ;MAAE;MAAM,GAAG;MAAa;MAAM;;UAE5C;IAEL,MAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,SAAK,MAAM,KAAK,OAAO;AACrB,SAAI,CAAC,EAAE,SAAS,MAAM,CAAE;KACxB,MAAM,OAAO,EAAE,QAAQ,OAAO,GAAG;KACjC,MAAM,MAAM,MAAM,SAAS,KAAK,MAAM,EAAE,CAAC;AACzC,SAAI,CAAC,IAAK;KACV,MAAM,EAAE,aAAa,SAAS,yBAAyB,IAAI;AAC3D,cAAS,QAAQ;MAAE;MAAM,GAAG;MAAa;MAAM;;;AAInD,eAAY,iBAAiB;;;AAKnC,QAAO,QAAQ,KAAI,UAAS;EAC1B,MAAM,WAAW,EAAE,GAAG,OAAO;AAC7B,OAAK,MAAM,MAAM,gBAAgB;GAC/B,MAAM,QAAQ,SAAS,GAAG;AAC1B,OAAI,CAAC,MAAO;AAEZ,OAAI,GAAG,SAAS,MAAM,QAAQ,MAAM,CAClC,UAAS,GAAG,QAAQ,MAAM,KAAI,OAAM;AAClC,SAAK,MAAM,iBAAiB,GAAG,cAAc;KAC3C,MAAM,SAAS,YAAY,iBAAiB;AAC5C,SAAI,OAAQ,QAAO;MAAE;MAAI,GAAG;MAAQ;;AAEtC,WAAO;KACP;YACO,OAAO,UAAU,SAC1B,MAAK,MAAM,iBAAiB,GAAG,cAAc;IAC3C,MAAM,SAAS,YAAY,iBAAiB;AAC5C,QAAI,QAAQ;AACV,cAAS,GAAG,QAAQ;MAAE,IAAI;MAAO,GAAG;MAAQ;AAC5C;;;;AAKR,SAAO;GACP;;;;ACtzBJ,MAAM,kBAAkB;AAExB,eAAe,qBAAwB,QAAoB,MAAiC;AAC1F,KAAI;AACF,SAAO,KAAK,MAAM,MAAM,OAAO,SAAS,KAAK,CAAC;SACxC;AACN,SAAO;;;AAaX,eAAsB,WAAW,OAAqD;CACpF,IAAI;CACJ,IAAI;AAEJ,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,YAAY,KAAK,eAAe,MAAM,EAAE,SAAS;AACvD,UAAQ,MAAM,QAAQ,UAAU;AAChC,UAAO,SAAQ,SAA0B,KAAK,WAAW,KAAK,CAAC;QAC1D;AACL,UAAQ,MAAM,MAAM,cAAc,gBAAgB;AAClD,UAAO,SAAQ,qBAAsC,OAAO,GAAG,gBAAgB,GAAG,OAAO;;CAG3F,MAAM,YAAY,MAAM,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC;AAGxD,SAFe,MAAM,QAAQ,IAAI,UAAU,IAAI,KAAK,CAAC,EAGlD,QAAQ,MAA4B,MAAM,QAAQ,CAAC,CAAC,EAAE,GAAG,CACzD,KAAI,WAAU;EACb,IAAI,MAAM;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,MAAM,MAAM;EACZ,QAAQ,MAAM,SAAS,OAAO,KAAK,MAAM,OAAO,CAAC,SAAS;EAC3D,EAAE,CACF,UAAU,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,IAAI,KAAK,CAAC;;AAQvD,eAAsB,UAAU,OAA4B,SAAkD;AAC5G,KAAI,OAAO,UAAU,SAEnB,QAAO,SADU,KAAK,eAAe,MAAM,EAAE,UAAU,GAAG,QAAQ,OAAO,CAC/B;AAE5C,QAAO,qBAAsC,OAAO,GAAG,gBAAgB,GAAG,QAAQ,OAAO;;AAG3F,eAAe,0BACb,QACA,YACA,SAC6D;CAC7D,MAAM,UAAkC,EAAE;CAC1C,IAAI,QAAQ;CAEZ,MAAM,UAAU,MAAM,QAAQ,IAC5B,QAAQ,IAAI,OAAO,UAAU;EAC3B,MAAM,cAAc,MAAM,OAAO,cAAc,GAAG,WAAW,GAAG,QAAQ;AACxE,SAAO,YACJ,KAAI,OAAM,GAAG,QAAQ,oBAAoB,GAAG,CAAC,CAC7C,QAAQ,QAAQ,MAAM,WAAW,YAAY,GAAG;GACnD,CACH;AAED,MAAK,MAAM,gBAAgB,QACzB,MAAK,MAAM,UAAU,cAAc;AACjC,UAAQ,WAAW,QAAQ,WAAW,KAAK;AAC3C;;AAIJ,QAAO;EAAE;EAAO;EAAS;;AAG3B,eAAe,4BACb,SACA,aACA,OAC6D;CAC7D,MAAM,UAAkC,EAAE;CAC1C,MAAM,gBAA6C,EAAE;AAErD,MAAK,MAAM,KAAK,OAAO;AACrB,MAAI,CAAC,EAAE,SAAS,MAAM,CAAE;EAExB,MAAM,QAAQ,EAAE,MAAM,uCAAuC;AAC7D,MAAI,CAAC,MAAO;EACZ,MAAM,SAAS,MAAM;AACrB,MAAI,CAAC,cAAc,QAAS,eAAc,0BAAU,IAAI,KAAK;AAC7D,gBAAc,QAAQ,IAAI,MAAM,GAAI;;CAGtC,IAAI,QAAQ;AACZ,MAAK,MAAM,CAAC,QAAQ,UAAU,OAAO,QAAQ,cAAc,EAAE;AAC3D,UAAQ,UAAU,MAAM;AACxB,WAAS,MAAM;;AAGjB,QAAO;EAAE;EAAO;EAAS;;AAG3B,eAAe,+BACb,QACA,YACA,YAC6D;CAC7D,MAAM,UAAkC,EAAE;CAC1C,IAAI,QAAQ;CAEZ,MAAM,UAAU,MAAM,QAAQ,IAC5B,WAAW,IAAI,OAAO,cAAc;AAGlC,SAAO;GAAE,QAAQ;GAAW,QAFd,MAAM,OAAO,cAAc,GAAG,WAAW,GAAG,YAAY,EAChD,QAAO,MAAK,EAAE,SAAS,MAAM,CAAC,CACT;GAAQ;GACnD,CACH;AAED,MAAK,MAAM,EAAE,QAAQ,WAAW,SAAS;AACvC,UAAQ,UAAU;AAClB,WAAS;;AAGX,QAAO;EAAE;EAAO;EAAS;;AAG3B,eAAe,0BACb,QACA,SACA,OACA,MAC6D;CAC7D,MAAM,UAAU,MAAM,QAAO,MAAK,EAAE,SAAS,MAAM,CAAC;AAEpD,KAAI,CAAC,KACH,QAAO;EAAE,OAAO,QAAQ;EAAQ,SAAS,EAAE,GAAG,QAAQ,QAAQ;EAAE;CAKlE,MAAM,UAAU,qBAAqB;CACrC,MAAM,UAAkC,EAAE;CAC1C,IAAI,QAAQ;CAEZ,MAAM,QAAQ,QAAQ,KAAI,MAAK,EAAE,QAAQ,OAAO,GAAG,CAAC;CACpD,MAAM,UAAU,MAAM,QAAQ,IAC5B,MAAM,IAAI,OAAO,SAAS;AAExB,UADkB,MAAM,OAAO,cAAc,GAAG,QAAQ,GAAG,OAAO,EAE/D,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC,CAChC,KAAI,MAAK,EAAE,QAAQ,SAAS,GAAG,CAAC;GACnC,CACH;AAED,MAAK,MAAM,eAAe,QACxB,MAAK,MAAM,UAAU,aAAa;AAChC,UAAQ,WAAW,QAAQ,WAAW,KAAK;AAC3C;;AAIJ,QAAO;EAAE;EAAO;EAAS;;AAG3B,eAAe,uBACb,QACA,YACA,WAC6D;CAC7D,MAAM,UAAkC,EAAE;CAC1C,IAAI,QAAQ;CAEZ,MAAM,UAAU,MAAM,QAAQ,IAC5B,UAAU,IAAI,OAAO,SAAS;EAC5B,MAAM,SAAS,KAAK,QAAQ,WAAW,GAAG;EAC1C,MAAM,OAAO,MAAM,qBAA8C,QAAQ,GAAG,WAAW,GAAG,OAAO;AACjG,SAAO;GAAE;GAAQ,OAAO,OAAO,OAAO,KAAK,KAAK,CAAC,SAAS;GAAG;GAC7D,CACH;AAED,MAAK,MAAM,EAAE,QAAQ,WAAW,SAAS;AACvC,UAAQ,UAAU;AAClB,WAAS;;AAGX,QAAO;EAAE;EAAO;EAAS;;AAkB3B,eAAsB,aACpB,OACA,OAC6D;CAC7D,MAAM,SAAqB,OAAO,UAAU,WAAW,IAAI,YAAY,MAAM,GAAG;CAChF,MAAM,OAAO,eAAe,MAAM;CAClC,MAAM,WAAW,sBAAsB,MAAM;CAC7C,MAAM,QAAQ,MAAM,OAAO,cAAc,KAAK;AAE9C,KAAI,MAAM,SAAS,YAAY;AAC7B,MAAI,CAAC,MAAM,KAET,QAAO,0BAA0B,QAAQ,MAAM,IAAI,OAAO,MAAM;AAGlE,UAAQ,UAAR;GACE,KAAK,OACH,QAAO,0BAA0B,QAAQ,MAAM,MAAM;GACvD,KAAK,SACH,QAAO,4BAA4B,QAAQ,MAAM,MAAM;GACzD,KAAK,YACH,QAAO,+BAA+B,QAAQ,MAAM,MAAM;GAC5D,KAAK,OACH,QAAO,0BAA0B,QAAQ,MAAM,IAAI,OAAO,KAAK;;;AAIrE,KAAI,MAAM,SAAS,cAAc;AAC/B,MAAI,CAAC,MAAM,KAGT,QAAO,uBAAuB,QAAQ,MADpB,MAAM,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC,CACF;AAExD,UAAQ,UAAR;GACE,KAAK,UAAU;IAEb,MAAM,YAAY,MAAM,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC;IACxD,MAAM,UAAkC,EAAE;AAC1C,SAAK,MAAM,KAAK,WAAW;KACzB,MAAM,QAAQ,EAAE,MAAM,uCAAuC;AAC7D,SAAI,OAAO;MACT,MAAM,OAAO,MAAM,qBAA8C,QAAQ,GAAG,KAAK,GAAG,IAAI;AACxF,cAAQ,MAAM,MAAO,OAAO,OAAO,KAAK,KAAK,CAAC,SAAS;;;AAI3D,WAAO;KAAE,OADK,OAAO,OAAO,QAAQ,CAAC,QAAQ,GAAG,MAAM,IAAI,GAAG,EAAE;KAC/C;KAAS;;GAE3B,KAAK,aAAa;IAEhB,MAAM,UAAkC,EAAE;IAC1C,IAAI,QAAQ;AACZ,SAAK,MAAM,aAAa,OAAO;KAE7B,MAAM,YADW,MAAM,OAAO,cAAc,GAAG,KAAK,GAAG,YAAY,EACzC,MAAK,MAAK,EAAE,SAAS,QAAQ,CAAC;AACxD,SAAI,UAAU;MACZ,MAAM,OAAO,MAAM,qBAA8C,QAAQ,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW;MAC5G,MAAM,QAAQ,OAAO,OAAO,KAAK,KAAK,CAAC,SAAS;AAChD,cAAQ,aAAa;AACrB,eAAS;;;AAGb,WAAO;KAAE;KAAO;KAAS;;GAE3B,KAAK,QAAQ;IAEX,MAAM,WAAW,MAAM,MAAK,MAAK,MAAM,GAAG,MAAM,GAAG,OAAO;AAC1D,QAAI,CAAC,SAAU,QAAO;KAAE,OAAO;KAAG,SAAS,EAAE;KAAE;IAC/C,MAAM,OAAO,MAAM,qBAA8C,QAAQ,GAAG,KAAK,GAAG,WAAW;IAC/F,MAAM,QAAQ,OAAO,OAAO,KAAK,KAAK,CAAC,SAAS;AAChD,WAAO;KAAE,OAAO;KAAO,SAAS,EAAE,GAAG,OAAO;KAAE;;GAEhD,QAGE,QAAO,uBAAuB,QAAQ,MADpB,MAAM,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC,CACF;;;AAM5D,KAAI,CAAC,MAAM,KAGT,QAAO;EAAE,OADO,MAAM,MAAK,MAAK,MAAM,YAAY,GACxB,IAAI;EAAG,SAAS,EAAE;EAAE;AAGhD,SAAQ,UAAR;EACE,KAAK,UAAU;GAEb,MAAM,UAAkC,EAAE;AAC1C,QAAK,MAAM,KAAK,OAAO;IACrB,MAAM,QAAQ,EAAE,MAAM,uCAAuC;AAC7D,QAAI,MAAO,SAAQ,MAAM,MAAO;;AAElC,UAAO;IAAE,OAAO,OAAO,KAAK,QAAQ,CAAC;IAAQ;IAAS;;EAExD,KAAK,aAAa;GAEhB,MAAM,UAAkC,EAAE;AAC1C,QAAK,MAAM,aAAa,MAEtB,MADiB,MAAM,OAAO,cAAc,GAAG,KAAK,GAAG,YAAY,EACtD,MAAK,MAAK,EAAE,SAAS,QAAQ,CAAC,CACzC,SAAQ,aAAa;AAGzB,UAAO;IAAE,OAAO,OAAO,KAAK,QAAQ,CAAC;IAAQ;IAAS;;EAExD,KAAK,OAGH,QAAO;GAAE,OADO,MAAM,MAAK,MAAK,MAAM,GAAG,MAAM,GAAG,OAAO,GAC/B,IAAI;GAAG,SAAS,EAAE;GAAE;EAEhD,SAAS;GAEP,MAAM,YAAY,MAAM,QAAO,MAAK,EAAE,SAAS,QAAQ,CAAC;GACxD,MAAM,UAAkC,EAAE;AAC1C,QAAK,MAAM,QAAQ,UACjB,SAAQ,KAAK,QAAQ,WAAW,GAAG,IAAI;AAEzC,UAAO;IAAE,OAAO,UAAU;IAAQ;IAAS;;;;AAKjD,eAAsB,WAAW,aAAqB,OAAuC;AAE3F,OAAM,UADW,KAAK,eAAe,YAAY,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,EACtD,OAAO,kBAAkB;AAGnD,OAAM,UAAU,kBAAkB,aAAa,MAAM,CAAC;AACtD,OAAM,UAAU,KAAK,eAAe,YAAY,EAAE,QAAQ,MAAM,GAAG,CAAC;;AAGtE,eAAsB,YAAY,aAAqB,SAAoC;CACzF,MAAM,QAAQ,MAAM,UAAU,aAAa,QAAQ;AACnD,KAAI,CAAC,MAAO,QAAO,EAAE;CAErB,MAAM,QAAQ,eAAe,YAAY;CACzC,MAAM,UAAoB,EAAE;CAE5B,MAAM,YAAY,KAAK,OAAO,UAAU,GAAG,QAAQ,OAAO;CAC1D,MAAM,cAAc,kBAAkB,aAAa,MAAM;CACzD,MAAM,WAAW,KAAK,OAAO,QAAQ,QAAQ;AAE7C,OAAM,GAAG,WAAW,EAAE,OAAO,MAAM,CAAC;AACpC,SAAQ,KAAK,UAAU,QAAQ,OAAO;AAEtC,KAAI;AACF,QAAM,GAAG,aAAa;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AACvD,UAAQ,KAAK,MAAM,gBAAgB,WAAW,MAAM,OAAO,GAAG,QAAQ,GAAG;SACnE;AAIR,KAAI;AACF,QAAM,GAAG,UAAU;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AACpD,UAAQ,KAAK,QAAQ,QAAQ,GAAG;SAC1B;AAIR,QAAO;;AAmBT,eAAsB,gBACpB,OACA,SAC2B;CAE3B,MAAM,UADY,OAAO,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,MAAM,WAAW,MAAM,EACtE,QAAO,MAAK,EAAE,OAAO,QAAQ;CAEtD,MAAM,SAAS,MAAM,QAAQ,IAC3B,OAAO,KAAI,MAAK,OAAO,UAAU,WAAW,UAAU,OAAO,EAAE,GAAG,GAAG,UAAU,OAAO,EAAE,GAAG,CAAC,CAC7F;CAED,MAAM,OAAyB,EAAE;AACjC,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO,OAAQ;AAEpB,OAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,MAAM,OAAO,EAAE;AAChE,OAAI,SAAS,SAAS,cAAc,SAAS,SAAS,YAAa;AAEnE,QADgB,MAAM,QAAQ,SAAS,MAAM,GAAG,SAAS,QAAQ,CAAC,SAAS,MAAM,EACrE,SAAS,QAAQ,CAC3B,MAAK,KAAK;IAAE,OAAO,MAAM;IAAI,OAAO;IAAW,MAAM,SAAS;IAAM,CAAC;;;AAK3E,QAAO;;AAKT,MAAa,kBAAkB;CAC7B;CAAU;CAAQ;CAAS;CAAO;CAAQ;CAAS;CAAS;CAAQ;CACpE;CAAY;CACZ;CAAU;CAAW;CAAW;CAAW;CAC3C;CAAW;CAAQ;CACnB;CAAS;CAAS;CAClB;CAAY;CACZ;CAAU;CAAS;CACpB;;;;;;;;;AAUD,MAAa,oBAAwD,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,OAAO;CACjG,MAAM,EAAE,KAAK,gBAAgB,CAAC,SAAS,sCAAsC;CAC7E,UAAU,EAAE,SAAS,CAAC,UAAU;CAChC,QAAQ,EAAE,SAAS,CAAC,UAAU;CAC9B,SAAS,EAAE,SAAS,CAAC,UAAU;CAC/B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CACvC,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU;CAC5D,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU;CACxF,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU;CAClE,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,aAAa,EAAE,QAAQ,CAAC,UAAU;CAClC,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CACtE,SAAS,6GAA6G;CACzH,OAAO,EAAE,QAAQ,CAAC,UAAU,CACzB,SAAS,wGAAwG;CACrH,CAAC,CAAC,QAAQ,CAAC,QACT,MAAM;AACL,MAAK,EAAE,SAAS,cAAc,EAAE,SAAS,gBAAgB,CAAC,EAAE,MAAO,QAAO;AAC1E,KAAI,EAAE,SAAS,aAAa,CAAC,EAAE,WAAW,EAAE,QAAQ,WAAW,GAAI,QAAO;AAC1E,QAAO;GAET,EAAE,SAAS,gFAA4E,CACxF,CAAC;AAIF,MAAM,oBAAoB,IAAI,IAAY,gBAAgB;;AAG1D,MAAM,oBAAoB,IAAI,IAAY;CAAC;CAAS;CAAS;CAAO,CAAC;;AAErE,MAAM,mBAAmB;;;;;;;;;AAmCzB,SAAS,cACP,KACA,MACA,WACA,QACA,UACA,OACM;AACN,KAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,SAAO,KAAK,UAAU,KAAK,sBAAsB;AACjD;;AAEF,KAAI,QAAQ,kBAAkB;AAC5B,SAAO,KAAK,UAAU,KAAK,0CAA0C,mBAAmB;AACxF;;CAGF,MAAM,MAAM;CACZ,MAAM,OAAO,IAAI;AAEjB,KAAI,CAAC,QAAQ,CAAC,kBAAkB,IAAI,KAAK,EAAE;AACzC,SAAO,KAAK,UAAU,KAAK,mBAAmB,KAAK,GAAG;AACtD;;AAMF,KAAI,IAAI,UAAU,KAAA,EAChB,KAAI,OAAO,IAAI,UAAU;MACnB,IAAI,MAAM,MAAM,KAAK,GAAI,QAAO,KAAK,UAAU,KAAK,qBAAqB;YACpE,OAAO,IAAI,UAAU,YAAY,IAAI,UAAU,QAAQ,CAAC,MAAM,QAAQ,IAAI,MAAM,EAAE;EAC3F,MAAM,UAAU,OAAO,QAAQ,IAAI,MAAiC;AACpE,MAAI,QAAQ,WAAW,EAAG,QAAO,KAAK,UAAU,KAAK,gCAAgC;AACrF,OAAK,MAAM,CAAC,QAAQ,UAAU,SAAS;AACrC,OAAI,CAAC,eAAe,KAAK,OAAO,CAC9B,QAAO,KAAK,UAAU,KAAK,kBAAkB,OAAO,+EAA+E;AAErI,OAAI,OAAO,UAAU,YAAY,MAAM,MAAM,KAAK,GAChD,QAAO,KAAK,UAAU,KAAK,kBAAkB,OAAO,8BAA8B;;OAItF,QAAO,KAAK,UAAU,KAAK,2DAA2D;AAG1F,KAAI,IAAI,UAAU,KAAA,MAAc,OAAO,IAAI,UAAU,YAAY,CAAC,OAAO,SAAS,IAAI,MAAM,EAC1F,QAAO,KAAK,UAAU,KAAK,oCAAoC;AAGjE,MAAK,SAAS,cAAc,SAAS,gBAAgB,CAAC,IAAI,MACxD,QAAO,KAAK,UAAU,KAAK,KAAK,KAAK,iCAAiC;AAExE,KAAI,SAAS,aAAa,CAAC,MAAM,QAAQ,IAAI,QAAQ,IAAI,IAAI,QAAQ,WAAW,GAC9E,QAAO,KAAK,UAAU,KAAK,mDAAmD;AAMhF,KAAI,SAAS,aAAa,CAAC,IAAI,UAAU,OAAO,IAAI,WAAW,YAAY,OAAO,KAAK,IAAI,OAAkC,CAAC,WAAW,GACvI,UAAS,KAAK,UAAU,KAAK,0HAA0H;AAIzJ,KAAI,IAAI,YAAY,KAAA,KAAa,SAAS,SACxC,QAAO,KAAK,UAAU,KAAK,iEAAiE,KAAK,GAAG;AAEtG,KAAI,IAAI,UAAU,KAAA,KAAa,SAAS,QACtC,QAAO,KAAK,UAAU,KAAK,8DAA8D,KAAK,GAAG;AAEnG,KAAI,IAAI,WAAW,KAAA,KAAa,SAAS,SACvC,QAAO,KAAK,UAAU,KAAK,gEAAgE,KAAK,GAAG;AAErG,KAAI,IAAI,WAAW,KAAA,KAAa,CAAC,kBAAkB,IAAI,KAAK,CAC1D,QAAO,KAAK,UAAU,KAAK,0EAA0E,KAAK,GAAG;AAE/G,KAAI,IAAI,YAAY,KAAA,KAAa,CAAC,kBAAkB,IAAI,KAAK,CAC3D,QAAO,KAAK,UAAU,KAAK,2EAA2E,KAAK,GAAG;AAKhH,KAAI,IAAI,WAAW,QAAQ,cAAc,YACvC,QAAO,KAAK,UAAU,KAAK,wFAAwF;AAGrH,KAAI,OAAO,IAAI,QAAQ,YAAY,OAAO,IAAI,QAAQ,YAAY,IAAI,MAAM,IAAI,IAC9E,QAAO,KAAK,UAAU,KAAK,UAAU,IAAI,IAAI,yBAAyB,IAAI,IAAI,GAAG;AAKnF,KAAI,OAAO,IAAI,YAAY,SACzB,KAAI;AAEF,MAAI,OAAO,IAAI,QAAQ;SACjB;AACN,SAAO,KAAK,UAAU,KAAK,oDAAoD,IAAI,QAAQ,GAAG;;AAIlG,KAAI,IAAI,YAAY,KAAA,EAClB,uBAAsB,KAAK,MAAM,MAAM,OAAO;AAKhD,KAAI,OAAO,IAAI,QAAQ,YAAY,kBAAkB,IAAI,KAAK,CAC5D,UAAS,KACP,UAAU,KAAK,gBAAgB,KAAK,iGACrC;AAKH,KAAI,IAAI,YAAY,KAAA,KAAa,kBAAkB,IAAI,KAAK,CAC1D,UAAS,KACP,UAAU,KAAK,iIAChB;AAGH,KAAI,IAAI,WAAW,KAAA,KAAa,OAAO,IAAI,WAAW,YAAY,IAAI,WAAW,KAC/E,MAAK,MAAM,CAAC,QAAQ,cAAc,OAAO,QAAQ,IAAI,OAAkC,EAAE;AACvF,MAAI,CAAC,oBAAoB,KAAK,OAAO,CACnC,QAAO,KAAK,UAAU,KAAK,GAAG,OAAO,2DAA2D;AAElG,gBAAc,WAAW,GAAG,KAAK,GAAG,UAAU,WAAW,QAAQ,UAAU,QAAQ,EAAE;;AAIzF,KAAI,OAAO,IAAI,UAAU;MACnB,CAAC,kBAAkB,IAAI,IAAI,MAAM,CACnC,QAAO,KAAK,UAAU,KAAK,yBAAyB,IAAI,MAAM,GAAG;YAE1D,IAAI,UAAU,KAAA,EACvB,eAAc,IAAI,OAAO,GAAG,KAAK,SAAS,WAAW,QAAQ,UAAU,QAAQ,EAAE;;;AAKrF,SAAS,sBAAsB,KAAkB,MAAc,MAAc,QAAwB;CACnG,MAAM,QAAQ,IAAI;CAClB,MAAM,WAAW,OAAO,UAAU;CAClC,MAAM,WAAW,OAAO,UAAU;AAElC,KAAI,SAAS,YAAY,MAAM,QAAQ,IAAI,QAAQ,IAAI,YAAY,CAAC,IAAI,QAAQ,SAAS,MAAM,EAAE;AAC/F,SAAO,KAAK,UAAU,KAAK,cAAc,MAAM,mCAAoC,IAAI,QAAqB,KAAK,KAAK,CAAC,GAAG;AAC1H;;CAEF,MAAM,cAAc;EAAC;EAAU;EAAW;EAAW;EAAW;EAAS,CAAC,SAAS,KAAK;CACxF,MAAM,eAAe,SAAS;CAC9B,MAAM,aAAa,SAAS;AAE5B,KAAI,eAAe,CAAC,SAClB,QAAO,KAAK,UAAU,KAAK,wCAAwC,KAAK,GAAG;UAClE,gBAAgB,OAAO,UAAU,UAC1C,QAAO,KAAK,UAAU,KAAK,yCAAyC,KAAK,GAAG;UACnE,cAAc,CAAC,MAAM,QAAQ,MAAM,CAC5C,QAAO,KAAK,UAAU,KAAK,wCAAwC,KAAK,GAAG;;;AAO/E,MAAM,mBAAmB;CAAC;CAAS;CAAQ;CAAS;CAAU;;;;;;;AAQ9D,MAAM,sBAA4C;CAChD;CAAU;CAAQ;CAAS;CAAO;CAAQ;CAAQ;CAAY;CAC/D;;AAeD,SAAS,gBAAgB,QAAoD;AAC3E,KAAI,CAAC,OAAQ,QAAO,EAAE;CACtB,MAAM,MAAwB,EAAE;AAChC,MAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,OAAO,EAAE;EACjD,MAAM,MAAM;EACZ,MAAM,OAAO,KAAK;AAClB,MAAI,OAAO,SAAS,YAAY,CAAC,iBAAiB,KAAkB,CAAE;AACtE,MAAI,KAAK;GAAE;GAAa;GAAmB,UAAU,KAAK,aAAa;GAAM,CAAC;;AAEhF,QAAO;;AAGT,SAAS,eAAe,GAAmB,GAA2B;CACpE,MAAM,SAAS,oBAAoB,QAAQ,EAAE,KAAK,GAAG,oBAAoB,QAAQ,EAAE,KAAK;AACxF,QAAO,WAAW,IAAI,SAAS,EAAE,MAAM,cAAc,EAAE,OAAO,KAAK;;;;;;;AAQrE,SAAS,cAAc,OAAuB;CAC5C,MAAM,QAAS,iBAAuC,QAAQ,MAAM;AACpE,KAAI,UAAU,GAAI,QAAO;CAEzB,MAAM,SAAS,MAAM,MAAM,IAAI;CAC/B,MAAM,QAAQ,iBAAiB,WAAU,SAAQ,OAAO,SAAS,KAAK,CAAC;AACvE,QAAO,UAAU,KAAK,OAAO,oBAAoB,iBAAiB,SAAS;;;;;;;;;;;;;;;;;AAkB7E,SAAgB,gBAAgB,MAAc,QAAyD;AAErG,KAAI,SAAS,aAAc,QAAO;EAAE,OAAO;EAAwB,MAAM;EAAc;CAEvF,MAAM,aAAa,gBAAgB,OAAO;AAC1C,KAAI,WAAW,WAAW,EAAG,QAAO;CAEpC,MAAM,QAAQ,WAAW,QAAO,MAAK,OAAO,SAAS,cAAc,EAAE,MAAM,CAAC,CAAC;AAC7E,KAAI,MAAM,SAAS,EAKjB,QAAO;EAAE,OAJI,MAAM,UAAU,GAAG,MAAM;GACpC,MAAM,SAAS,cAAc,EAAE,MAAM,GAAG,cAAc,EAAE,MAAM;AAC9D,UAAO,WAAW,IAAI,SAAS,eAAe,GAAG,EAAE;IACnD,CAAC,GACkB;EAAO,MAAM;EAAc;CAGlD,MAAM,WAAW,WAAW,QAAO,MAAK,EAAE,SAAS;AACnD,KAAI,SAAS,SAAS,EACpB,QAAO;EAAE,OAAO,SAAS,SAAS,eAAe,CAAC,GAAI;EAAO,MAAM;EAAwB;AAG7F,QAAO;EAAE,OAAO,WAAW,SAAS,eAAe,CAAC,GAAI;EAAO,MAAM;EAAe;;;;;;;;;;;AAYtF,SAAgB,iBACd,OACuB;CACvB,MAAM,SAAmB,EAAE;CAC3B,MAAM,WAAqB,EAAE;CAC7B,MAAM,aAAa,MAAM;AAEzB,KAAI,eAAe,KAAA,KAAa,eAAe,QAAQ,eAAe,GACpE,QAAO,KAAK,8GAA0G;UAC7G,OAAO,eAAe,SAC/B,QAAO,KAAK,gDAAgD,OAAO,WAAW,GAAG;UACxE,MAAM,SAAS;MACpB,eAAe,uBACjB,QAAO,KAAK,4CAA4C,uBAAuB,8DAA8D,WAAW,IAAI;YAErJ,CAAC,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,CAAC,WAAW,EAC/D,QAAO,KAAK,2BAA2B,WAAW,kDAAkD;UAC3F,EAAE,cAAc,MAAM,QAG/B,QAAO,KACL,iCAAiC,WAAW,gCACzC,eAAe,yBAAyB,KAAK,uBAAuB,wCAAwC,IAChH;MACI;EACL,MAAM,MAAM,MAAM,OAAO;EACzB,MAAM,OAAO,KAAK;AAClB,MAAI,OAAO,SAAS,YAAY,CAAC,iBAAiB,KAAkB,CAClE,QAAO,KAAK,iCAAiC,WAAW,cAAc,KAAK,8BAA8B,kBAAkB,KAAK,KAAK,CAAC,GAAG;WAChI,KAAK,aAAa,KAC3B,UAAS,KAAK,2CAA2C,WAAW,sEAAsE;;AAM9I,QAAO;EAAE;EAAQ;EAAU;;;;;;AAO7B,SAAgB,wBAId,OACuB;CACvB,MAAM,SAAmB,EAAE;CAC3B,MAAM,WAAqB,EAAE;AAG7B,KAAI,CAAC,6BAA6B,KAAK,MAAM,GAAG,CAC9C,QAAO,KAAK,qBAAqB,MAAM,GAAG,uBAAuB;AAInE,KAAI,MAAM,SAAS,gBAAgB,MAAM,UAAU,OAAO,KAAK,MAAM,OAAO,CAAC,SAAS,EACpF,QAAO,KAAK,iFAAiF;CAK/F,MAAM,cAAc,iBAAiB,MAAM;AAC3C,QAAO,KAAK,GAAG,YAAY,OAAO;AAClC,UAAS,KAAK,GAAG,YAAY,SAAS;AAEtC,KAAI,MAAM,OACR,MAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,MAAM,OAAO,EAAE;AAChE,MAAI,CAAC,oBAAoB,KAAK,UAAU,CACtC,QAAO,KAAK,UAAU,UAAU,2DAA2D;AAE7F,gBAAc,UAAU,WAAW,MAAM,MAAM,QAAQ,UAAU,EAAE;;AAIvE,QAAO;EAAE;EAAQ;EAAU"}
@@ -297,4 +297,4 @@ var w = async (t, s) => i().then((r) => r.transform(t, s)), l = async (t, s) =>
297
297
  //#endregion
298
298
  export { P as compile, b as convertToTSX, l as parse, g as teardown, w as transform };
299
299
 
300
- //# sourceMappingURL=node-BxujauDw.mjs.map
300
+ //# sourceMappingURL=node-DUGiIkv1.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-BxujauDw.mjs","names":["g","y","v","w","b","d","m","c","f"],"sources":["../../../node_modules/.pnpm/@astrojs+compiler@2.13.1/node_modules/@astrojs/compiler/dist/chunk-W5DTLHV4.js","../../../node_modules/.pnpm/@astrojs+compiler@2.13.1/node_modules/@astrojs/compiler/dist/node/index.js"],"sourcesContent":["import g from\"crypto\";import _ from\"fs\";import{TextDecoder as b,TextEncoder as v}from\"util\";globalThis.fs||Object.defineProperty(globalThis,\"fs\",{value:_});globalThis.process||Object.defineProperties(globalThis,\"process\",{value:process});globalThis.crypto||Object.defineProperty(globalThis,\"crypto\",{value:g.webcrypto?g.webcrypto:{getRandomValues(m){return g.randomFillSync(m)}}});globalThis.performance||Object.defineProperty(globalThis,\"performance\",{value:{now(){let[m,o]=process.hrtime();return m*1e3+o/1e6}}});var y=new v(\"utf-8\"),w=new b(\"utf-8\");var d=class{constructor(){this.argv=[\"js\"],this.env={},this.exit=t=>{t!==0&&console.warn(\"exit code:\",t)},this._exitPromise=new Promise(t=>{this._resolveExitPromise=t}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;let o=(t,e)=>{this.mem.setUint32(t+0,e,!0),this.mem.setUint32(t+4,Math.floor(e/4294967296),!0)},n=t=>{let e=this.mem.getUint32(t+0,!0),s=this.mem.getInt32(t+4,!0);return e+s*4294967296},r=t=>{let e=this.mem.getFloat64(t,!0);if(e===0)return;if(!isNaN(e))return e;let s=this.mem.getUint32(t,!0);return this._values[s]},l=(t,e)=>{if(typeof e==\"number\"&&e!==0){if(isNaN(e)){this.mem.setUint32(t+4,2146959360,!0),this.mem.setUint32(t,0,!0);return}this.mem.setFloat64(t,e,!0);return}if(e===void 0){this.mem.setFloat64(t,0,!0);return}let i=this._ids.get(e);i===void 0&&(i=this._idPool.pop(),i===void 0&&(i=this._values.length),this._values[i]=e,this._goRefCounts[i]=0,this._ids.set(e,i)),this._goRefCounts[i]++;let a=0;switch(typeof e){case\"object\":e!==null&&(a=1);break;case\"string\":a=2;break;case\"symbol\":a=3;break;case\"function\":a=4;break}this.mem.setUint32(t+4,2146959360|a,!0),this.mem.setUint32(t,i,!0)},c=t=>{let e=n(t+0),s=n(t+8);return new Uint8Array(this._inst.exports.mem.buffer,e,s)},f=t=>{let e=n(t+0),s=n(t+8),i=new Array(s);for(let a=0;a<s;a++)i[a]=r(e+a*8);return i},u=t=>{let e=n(t+0),s=n(t+8);return w.decode(new DataView(this._inst.exports.mem.buffer,e,s))},h=Date.now()-performance.now();this.importObject={gojs:{\"runtime.wasmExit\":t=>{t>>>=0;let e=this.mem.getInt32(t+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(e)},\"runtime.wasmWrite\":t=>{t>>>=0;let e=n(t+8),s=n(t+16),i=this.mem.getInt32(t+24,!0);_.writeSync(e,new Uint8Array(this._inst.exports.mem.buffer,s,i))},\"runtime.resetMemoryDataView\":t=>{t>>>=0,this.mem=new DataView(this._inst.exports.mem.buffer)},\"runtime.nanotime1\":t=>{t>>>=0,o(t+8,(h+performance.now())*1e6)},\"runtime.walltime\":t=>{t>>>=0;let e=new Date().getTime();o(t+8,e/1e3),this.mem.setInt32(t+16,e%1e3*1e6,!0)},\"runtime.scheduleTimeoutEvent\":t=>{t>>>=0;let e=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(e,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(e);)console.warn(\"scheduleTimeoutEvent: missed timeout event\"),this._resume()},n(t+8)+1)),this.mem.setInt32(t+16,e,!0)},\"runtime.clearTimeoutEvent\":t=>{t>>>=0;let e=this.mem.getInt32(t+8,!0);clearTimeout(this._scheduledTimeouts.get(e)),this._scheduledTimeouts.delete(e)},\"runtime.getRandomData\":t=>{t>>>=0,globalThis.crypto.getRandomValues(c(t+8))},\"syscall/js.finalizeRef\":t=>{t>>>=0;let e=this.mem.getUint32(t+8,!0);if(this._goRefCounts[e]--,this._goRefCounts[e]===0){let s=this._values[e];this._values[e]=null,this._ids.delete(s),this._idPool.push(e)}},\"syscall/js.stringVal\":t=>{t>>>=0,l(t+24,u(t+8))},\"syscall/js.valueGet\":t=>{t>>>=0;let e=Reflect.get(r(t+8),u(t+16));t=this._inst.exports.getsp()>>>0,l(t+32,e)},\"syscall/js.valueSet\":t=>{t>>>=0,Reflect.set(r(t+8),u(t+16),r(t+32))},\"syscall/js.valueDelete\":t=>{t>>>=0,Reflect.deleteProperty(r(t+8),u(t+16))},\"syscall/js.valueIndex\":t=>{t>>>=0,l(t+24,Reflect.get(r(t+8),n(t+16)))},\"syscall/js.valueSetIndex\":t=>{t>>>=0,Reflect.set(r(t+8),n(t+16),r(t+24))},\"syscall/js.valueCall\":t=>{t>>>=0;try{let e=r(t+8),s=Reflect.get(e,u(t+16)),i=f(t+32),a=Reflect.apply(s,e,i);t=this._inst.exports.getsp()>>>0,l(t+56,a),this.mem.setUint8(t+64,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+56,e),this.mem.setUint8(t+64,0)}},\"syscall/js.valueInvoke\":t=>{t>>>=0;try{let e=r(t+8),s=f(t+16),i=Reflect.apply(e,void 0,s);t=this._inst.exports.getsp()>>>0,l(t+40,i),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+40,e),this.mem.setUint8(t+48,0)}},\"syscall/js.valueNew\":t=>{t>>>=0;try{let e=r(t+8),s=f(t+16),i=Reflect.construct(e,s);t=this._inst.exports.getsp()>>>0,l(t+40,i),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+40,e),this.mem.setUint8(t+48,0)}},\"syscall/js.valueLength\":t=>{t>>>=0,o(t+16,Number.parseInt(r(t+8).length))},\"syscall/js.valuePrepareString\":t=>{t>>>=0;let e=y.encode(String(r(t+8)));l(t+16,e),o(t+24,e.length)},\"syscall/js.valueLoadString\":t=>{t>>>=0;let e=r(t+8);c(t+16).set(e)},\"syscall/js.valueInstanceOf\":t=>{t>>>=0,this.mem.setUint8(t+24,r(t+8)instanceof r(t+16)?1:0)},\"syscall/js.copyBytesToGo\":t=>{t>>>=0;let e=c(t+8),s=r(t+32);if(!(s instanceof Uint8Array||s instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}let i=s.subarray(0,e.length);e.set(i),o(t+40,i.length),this.mem.setUint8(t+48,1)},\"syscall/js.copyBytesToJS\":t=>{t>>>=0;let e=r(t+8),s=c(t+16);if(!(e instanceof Uint8Array||e instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}let i=s.subarray(0,e.length);e.set(i),o(t+40,i.length),this.mem.setUint8(t+48,1)},debug:t=>{console.log(t)}}}}async run(o){if(!(o instanceof WebAssembly.Instance))throw new Error(\"Go.run: WebAssembly.Instance expected\");this._inst=o,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[Number.NaN,0,null,!0,!1,globalThis,this],this._goRefCounts=new Array(this._values.length).fill(Number.POSITIVE_INFINITY),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[globalThis,5],[this,6]]),this._idPool=[],this.exited=!1;let n=4096,r=h=>{let t=n,e=y.encode(`${h}\\0`);return new Uint8Array(this.mem.buffer,n,e.length).set(e),n+=e.length,n%8!==0&&(n+=8-n%8),t},l=this.argv.length,c=[];this.argv.forEach(h=>{c.push(r(h))}),c.push(0),Object.keys(this.env).sort().forEach(h=>{c.push(r(`${h}=${this.env[h]}`))}),c.push(0);let u=n;c.forEach(h=>{this.mem.setUint32(n,h,!0),this.mem.setUint32(n+4,0,!0),n+=8}),this._inst.exports.run(l,u),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error(\"Go program has already exited\");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(o){let n=this;return function(){let r={id:o,this:this,args:arguments};return n._pendingEvent=r,n._resume(),r.result}}};export{d as a};\n","import{a as c}from\"../chunk-W5DTLHV4.js\";import{promises as m}from\"fs\";import{fileURLToPath as f}from\"url\";var w=async(t,s)=>i().then(r=>r.transform(t,s)),l=async(t,s)=>i().then(r=>r.parse(t,s)),b=async(t,s)=>i().then(r=>r.convertToTSX(t,s)),P=async t=>{let{default:s}=await import(`data:text/javascript;charset=utf-8;base64,${Buffer.from(t).toString(\"base64\")}`);return s},n,g=()=>{n=void 0,globalThis[\"@astrojs/compiler\"]=void 0},i=()=>(n||(n=d().catch(t=>{throw n=void 0,t})),n),y=async(t,s)=>{let r;return r=await(async()=>{let o=await m.readFile(t).then(e=>e.buffer);return WebAssembly.instantiate(new Uint8Array(o),s)})(),r},d=async()=>{let t=new c,s=await y(f(new URL(\"../astro.wasm\",import.meta.url)),t.importObject);t.run(s.instance);let r=globalThis[\"@astrojs/compiler\"];return{transform:(a,o)=>new Promise(e=>{try{e(r.transform(a,o||{}))}catch(p){throw n=void 0,p}}),parse:(a,o)=>new Promise(e=>e(r.parse(a,o||{}))).catch(e=>{throw n=void 0,e}).then(e=>({...e,ast:JSON.parse(e.ast)})),convertToTSX:(a,o)=>new Promise(e=>e(r.convertToTSX(a,o||{}))).catch(e=>{throw n=void 0,e}).then(e=>({...e,map:JSON.parse(e.map)}))}};export{P as compile,b as convertToTSX,l as parse,g as teardown,w as transform};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"node-DUGiIkv1.mjs","names":["g","y","v","w","b","d","m","c","f"],"sources":["../../../node_modules/.pnpm/@astrojs+compiler@2.13.1/node_modules/@astrojs/compiler/dist/chunk-W5DTLHV4.js","../../../node_modules/.pnpm/@astrojs+compiler@2.13.1/node_modules/@astrojs/compiler/dist/node/index.js"],"sourcesContent":["import g from\"crypto\";import _ from\"fs\";import{TextDecoder as b,TextEncoder as v}from\"util\";globalThis.fs||Object.defineProperty(globalThis,\"fs\",{value:_});globalThis.process||Object.defineProperties(globalThis,\"process\",{value:process});globalThis.crypto||Object.defineProperty(globalThis,\"crypto\",{value:g.webcrypto?g.webcrypto:{getRandomValues(m){return g.randomFillSync(m)}}});globalThis.performance||Object.defineProperty(globalThis,\"performance\",{value:{now(){let[m,o]=process.hrtime();return m*1e3+o/1e6}}});var y=new v(\"utf-8\"),w=new b(\"utf-8\");var d=class{constructor(){this.argv=[\"js\"],this.env={},this.exit=t=>{t!==0&&console.warn(\"exit code:\",t)},this._exitPromise=new Promise(t=>{this._resolveExitPromise=t}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;let o=(t,e)=>{this.mem.setUint32(t+0,e,!0),this.mem.setUint32(t+4,Math.floor(e/4294967296),!0)},n=t=>{let e=this.mem.getUint32(t+0,!0),s=this.mem.getInt32(t+4,!0);return e+s*4294967296},r=t=>{let e=this.mem.getFloat64(t,!0);if(e===0)return;if(!isNaN(e))return e;let s=this.mem.getUint32(t,!0);return this._values[s]},l=(t,e)=>{if(typeof e==\"number\"&&e!==0){if(isNaN(e)){this.mem.setUint32(t+4,2146959360,!0),this.mem.setUint32(t,0,!0);return}this.mem.setFloat64(t,e,!0);return}if(e===void 0){this.mem.setFloat64(t,0,!0);return}let i=this._ids.get(e);i===void 0&&(i=this._idPool.pop(),i===void 0&&(i=this._values.length),this._values[i]=e,this._goRefCounts[i]=0,this._ids.set(e,i)),this._goRefCounts[i]++;let a=0;switch(typeof e){case\"object\":e!==null&&(a=1);break;case\"string\":a=2;break;case\"symbol\":a=3;break;case\"function\":a=4;break}this.mem.setUint32(t+4,2146959360|a,!0),this.mem.setUint32(t,i,!0)},c=t=>{let e=n(t+0),s=n(t+8);return new Uint8Array(this._inst.exports.mem.buffer,e,s)},f=t=>{let e=n(t+0),s=n(t+8),i=new Array(s);for(let a=0;a<s;a++)i[a]=r(e+a*8);return i},u=t=>{let e=n(t+0),s=n(t+8);return w.decode(new DataView(this._inst.exports.mem.buffer,e,s))},h=Date.now()-performance.now();this.importObject={gojs:{\"runtime.wasmExit\":t=>{t>>>=0;let e=this.mem.getInt32(t+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(e)},\"runtime.wasmWrite\":t=>{t>>>=0;let e=n(t+8),s=n(t+16),i=this.mem.getInt32(t+24,!0);_.writeSync(e,new Uint8Array(this._inst.exports.mem.buffer,s,i))},\"runtime.resetMemoryDataView\":t=>{t>>>=0,this.mem=new DataView(this._inst.exports.mem.buffer)},\"runtime.nanotime1\":t=>{t>>>=0,o(t+8,(h+performance.now())*1e6)},\"runtime.walltime\":t=>{t>>>=0;let e=new Date().getTime();o(t+8,e/1e3),this.mem.setInt32(t+16,e%1e3*1e6,!0)},\"runtime.scheduleTimeoutEvent\":t=>{t>>>=0;let e=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(e,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(e);)console.warn(\"scheduleTimeoutEvent: missed timeout event\"),this._resume()},n(t+8)+1)),this.mem.setInt32(t+16,e,!0)},\"runtime.clearTimeoutEvent\":t=>{t>>>=0;let e=this.mem.getInt32(t+8,!0);clearTimeout(this._scheduledTimeouts.get(e)),this._scheduledTimeouts.delete(e)},\"runtime.getRandomData\":t=>{t>>>=0,globalThis.crypto.getRandomValues(c(t+8))},\"syscall/js.finalizeRef\":t=>{t>>>=0;let e=this.mem.getUint32(t+8,!0);if(this._goRefCounts[e]--,this._goRefCounts[e]===0){let s=this._values[e];this._values[e]=null,this._ids.delete(s),this._idPool.push(e)}},\"syscall/js.stringVal\":t=>{t>>>=0,l(t+24,u(t+8))},\"syscall/js.valueGet\":t=>{t>>>=0;let e=Reflect.get(r(t+8),u(t+16));t=this._inst.exports.getsp()>>>0,l(t+32,e)},\"syscall/js.valueSet\":t=>{t>>>=0,Reflect.set(r(t+8),u(t+16),r(t+32))},\"syscall/js.valueDelete\":t=>{t>>>=0,Reflect.deleteProperty(r(t+8),u(t+16))},\"syscall/js.valueIndex\":t=>{t>>>=0,l(t+24,Reflect.get(r(t+8),n(t+16)))},\"syscall/js.valueSetIndex\":t=>{t>>>=0,Reflect.set(r(t+8),n(t+16),r(t+24))},\"syscall/js.valueCall\":t=>{t>>>=0;try{let e=r(t+8),s=Reflect.get(e,u(t+16)),i=f(t+32),a=Reflect.apply(s,e,i);t=this._inst.exports.getsp()>>>0,l(t+56,a),this.mem.setUint8(t+64,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+56,e),this.mem.setUint8(t+64,0)}},\"syscall/js.valueInvoke\":t=>{t>>>=0;try{let e=r(t+8),s=f(t+16),i=Reflect.apply(e,void 0,s);t=this._inst.exports.getsp()>>>0,l(t+40,i),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+40,e),this.mem.setUint8(t+48,0)}},\"syscall/js.valueNew\":t=>{t>>>=0;try{let e=r(t+8),s=f(t+16),i=Reflect.construct(e,s);t=this._inst.exports.getsp()>>>0,l(t+40,i),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,l(t+40,e),this.mem.setUint8(t+48,0)}},\"syscall/js.valueLength\":t=>{t>>>=0,o(t+16,Number.parseInt(r(t+8).length))},\"syscall/js.valuePrepareString\":t=>{t>>>=0;let e=y.encode(String(r(t+8)));l(t+16,e),o(t+24,e.length)},\"syscall/js.valueLoadString\":t=>{t>>>=0;let e=r(t+8);c(t+16).set(e)},\"syscall/js.valueInstanceOf\":t=>{t>>>=0,this.mem.setUint8(t+24,r(t+8)instanceof r(t+16)?1:0)},\"syscall/js.copyBytesToGo\":t=>{t>>>=0;let e=c(t+8),s=r(t+32);if(!(s instanceof Uint8Array||s instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}let i=s.subarray(0,e.length);e.set(i),o(t+40,i.length),this.mem.setUint8(t+48,1)},\"syscall/js.copyBytesToJS\":t=>{t>>>=0;let e=r(t+8),s=c(t+16);if(!(e instanceof Uint8Array||e instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}let i=s.subarray(0,e.length);e.set(i),o(t+40,i.length),this.mem.setUint8(t+48,1)},debug:t=>{console.log(t)}}}}async run(o){if(!(o instanceof WebAssembly.Instance))throw new Error(\"Go.run: WebAssembly.Instance expected\");this._inst=o,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[Number.NaN,0,null,!0,!1,globalThis,this],this._goRefCounts=new Array(this._values.length).fill(Number.POSITIVE_INFINITY),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[globalThis,5],[this,6]]),this._idPool=[],this.exited=!1;let n=4096,r=h=>{let t=n,e=y.encode(`${h}\\0`);return new Uint8Array(this.mem.buffer,n,e.length).set(e),n+=e.length,n%8!==0&&(n+=8-n%8),t},l=this.argv.length,c=[];this.argv.forEach(h=>{c.push(r(h))}),c.push(0),Object.keys(this.env).sort().forEach(h=>{c.push(r(`${h}=${this.env[h]}`))}),c.push(0);let u=n;c.forEach(h=>{this.mem.setUint32(n,h,!0),this.mem.setUint32(n+4,0,!0),n+=8}),this._inst.exports.run(l,u),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error(\"Go program has already exited\");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(o){let n=this;return function(){let r={id:o,this:this,args:arguments};return n._pendingEvent=r,n._resume(),r.result}}};export{d as a};\n","import{a as c}from\"../chunk-W5DTLHV4.js\";import{promises as m}from\"fs\";import{fileURLToPath as f}from\"url\";var w=async(t,s)=>i().then(r=>r.transform(t,s)),l=async(t,s)=>i().then(r=>r.parse(t,s)),b=async(t,s)=>i().then(r=>r.convertToTSX(t,s)),P=async t=>{let{default:s}=await import(`data:text/javascript;charset=utf-8;base64,${Buffer.from(t).toString(\"base64\")}`);return s},n,g=()=>{n=void 0,globalThis[\"@astrojs/compiler\"]=void 0},i=()=>(n||(n=d().catch(t=>{throw n=void 0,t})),n),y=async(t,s)=>{let r;return r=await(async()=>{let o=await m.readFile(t).then(e=>e.buffer);return WebAssembly.instantiate(new Uint8Array(o),s)})(),r},d=async()=>{let t=new c,s=await y(f(new URL(\"../astro.wasm\",import.meta.url)),t.importObject);t.run(s.instance);let r=globalThis[\"@astrojs/compiler\"];return{transform:(a,o)=>new Promise(e=>{try{e(r.transform(a,o||{}))}catch(p){throw n=void 0,p}}),parse:(a,o)=>new Promise(e=>e(r.parse(a,o||{}))).catch(e=>{throw n=void 0,e}).then(e=>({...e,ast:JSON.parse(e.ast)})),convertToTSX:(a,o)=>new Promise(e=>e(r.convertToTSX(a,o||{}))).catch(e=>{throw n=void 0,e}).then(e=>({...e,map:JSON.parse(e.map)}))}};export{P as compile,b as convertToTSX,l as parse,g as teardown,w as transform};\n"],"x_google_ignoreList":[0,1],"mappings":";;;;;AAA4F,WAAW,MAAI,OAAO,eAAe,YAAW,MAAK,EAAC,OAAM,GAAE,CAAC;AAAC,WAAW,WAAS,OAAO,iBAAiB,YAAW,WAAU,EAAC,OAAM,SAAQ,CAAC;AAAC,WAAW,UAAQ,OAAO,eAAe,YAAW,UAAS,EAAC,OAAMA,IAAE,YAAUA,IAAE,YAAU,EAAC,gBAAgB,GAAE;AAAC,QAAOA,IAAE,eAAe,EAAE;GAAE,EAAC,CAAC;AAAC,WAAW,eAAa,OAAO,eAAe,YAAW,eAAc,EAAC,OAAM,EAAC,MAAK;CAAC,IAAG,CAAC,GAAE,KAAG,QAAQ,QAAQ;AAAC,QAAO,IAAE,MAAI,IAAE;GAAK,EAAC,CAAC;AAAC,IAAIC,MAAE,IAAIC,YAAE,QAAQ,EAACC,MAAE,IAAIC,YAAE,QAAQ;AAAC,IAAIC,MAAE,MAAK;CAAC,cAAa;AAAC,OAAK,OAAK,CAAC,KAAK,EAAC,KAAK,MAAI,EAAE,EAAC,KAAK,QAAK,MAAG;AAAC,SAAI,KAAG,QAAQ,KAAK,cAAa,EAAE;KAAE,KAAK,eAAa,IAAI,SAAQ,MAAG;AAAC,QAAK,sBAAoB;IAAG,EAAC,KAAK,gBAAc,MAAK,KAAK,qCAAmB,IAAI,KAAG,EAAC,KAAK,yBAAuB;EAAE,IAAI,KAAG,GAAE,MAAI;AAAC,QAAK,IAAI,UAAU,IAAE,GAAE,GAAE,CAAC,EAAE,EAAC,KAAK,IAAI,UAAU,IAAE,GAAE,KAAK,MAAM,IAAE,WAAW,EAAC,CAAC,EAAE;KAAE,KAAE,MAAG;AAA8D,UAAvD,KAAK,IAAI,UAAU,IAAE,GAAE,CAAC,EAAE,GAAG,KAAK,IAAI,SAAS,IAAE,GAAE,CAAC,EAAE,GAAY;KAAY,KAAE,MAAG;GAAC,IAAI,IAAE,KAAK,IAAI,WAAW,GAAE,CAAC,EAAE;AAAC,OAAG,MAAI,EAAE;AAAO,OAAG,CAAC,MAAM,EAAE,CAAC,QAAO;GAAE,IAAI,IAAE,KAAK,IAAI,UAAU,GAAE,CAAC,EAAE;AAAC,UAAO,KAAK,QAAQ;KAAI,KAAG,GAAE,MAAI;AAAC,OAAG,OAAO,KAAG,YAAU,MAAI,GAAE;AAAC,QAAG,MAAM,EAAE,EAAC;AAAC,UAAK,IAAI,UAAU,IAAE,GAAE,YAAW,CAAC,EAAE,EAAC,KAAK,IAAI,UAAU,GAAE,GAAE,CAAC,EAAE;AAAC;;AAAO,SAAK,IAAI,WAAW,GAAE,GAAE,CAAC,EAAE;AAAC;;AAAO,OAAG,MAAI,KAAK,GAAE;AAAC,SAAK,IAAI,WAAW,GAAE,GAAE,CAAC,EAAE;AAAC;;GAAO,IAAI,IAAE,KAAK,KAAK,IAAI,EAAE;AAAC,SAAI,KAAK,MAAI,IAAE,KAAK,QAAQ,KAAK,EAAC,MAAI,KAAK,MAAI,IAAE,KAAK,QAAQ,SAAQ,KAAK,QAAQ,KAAG,GAAE,KAAK,aAAa,KAAG,GAAE,KAAK,KAAK,IAAI,GAAE,EAAE,GAAE,KAAK,aAAa;GAAK,IAAI,IAAE;AAAE,WAAO,OAAO,GAAd;IAAiB,KAAI;AAAS,WAAI,SAAO,IAAE;AAAG;IAAM,KAAI;AAAS,SAAE;AAAE;IAAM,KAAI;AAAS,SAAE;AAAE;IAAM,KAAI;AAAW,SAAE;AAAE;;AAAM,QAAK,IAAI,UAAU,IAAE,GAAE,aAAW,GAAE,CAAC,EAAE,EAAC,KAAK,IAAI,UAAU,GAAE,GAAE,CAAC,EAAE;KAAE,KAAE,MAAG;GAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,EAAE;AAAC,UAAO,IAAI,WAAW,KAAK,MAAM,QAAQ,IAAI,QAAO,GAAE,EAAE;KAAE,KAAE,MAAG;GAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,IAAI,MAAM,EAAE;AAAC,QAAI,IAAI,IAAE,GAAE,IAAE,GAAE,IAAI,GAAE,KAAG,EAAE,IAAE,IAAE,EAAE;AAAC,UAAO;KAAG,KAAE,MAAG;GAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,EAAE;AAAC,UAAOF,IAAE,OAAO,IAAI,SAAS,KAAK,MAAM,QAAQ,IAAI,QAAO,GAAE,EAAE,CAAC;KAAE,IAAE,KAAK,KAAK,GAAC,YAAY,KAAK;AAAC,OAAK,eAAa,EAAC,MAAK;GAAC,qBAAmB,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,KAAK,IAAI,SAAS,IAAE,GAAE,CAAC,EAAE;AAAC,SAAK,SAAO,CAAC,GAAE,OAAO,KAAK,OAAM,OAAO,KAAK,SAAQ,OAAO,KAAK,cAAa,OAAO,KAAK,MAAK,OAAO,KAAK,SAAQ,KAAK,KAAK,EAAE;;GAAE,sBAAoB,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,GAAG,EAAC,IAAE,KAAK,IAAI,SAAS,IAAE,IAAG,CAAC,EAAE;AAAC,MAAE,UAAU,GAAE,IAAI,WAAW,KAAK,MAAM,QAAQ,IAAI,QAAO,GAAE,EAAE,CAAC;;GAAE,gCAA8B,MAAG;AAAC,WAAK,GAAE,KAAK,MAAI,IAAI,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO;;GAAE,sBAAoB,MAAG;AAAC,WAAK,GAAE,EAAE,IAAE,IAAG,IAAE,YAAY,KAAK,IAAE,IAAI;;GAAE,qBAAmB,MAAG;AAAC,WAAK;IAAE,IAAI,qBAAE,IAAI,MAAM,EAAC,SAAS;AAAC,MAAE,IAAE,GAAE,IAAE,IAAI,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,IAAE,MAAI,KAAI,CAAC,EAAE;;GAAE,iCAA+B,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,KAAK;AAAuB,SAAK,0BAAyB,KAAK,mBAAmB,IAAI,GAAE,iBAAe;AAAC,UAAI,KAAK,SAAS,EAAC,KAAK,mBAAmB,IAAI,EAAE,EAAE,SAAQ,KAAK,6CAA6C,EAAC,KAAK,SAAS;OAAE,EAAE,IAAE,EAAE,GAAC,EAAE,CAAC,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,GAAE,CAAC,EAAE;;GAAE,8BAA4B,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,KAAK,IAAI,SAAS,IAAE,GAAE,CAAC,EAAE;AAAC,iBAAa,KAAK,mBAAmB,IAAI,EAAE,CAAC,EAAC,KAAK,mBAAmB,OAAO,EAAE;;GAAE,0BAAwB,MAAG;AAAC,WAAK,GAAE,WAAW,OAAO,gBAAgB,EAAE,IAAE,EAAE,CAAC;;GAAE,2BAAyB,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,KAAK,IAAI,UAAU,IAAE,GAAE,CAAC,EAAE;AAAC,QAAG,KAAK,aAAa,MAAK,KAAK,aAAa,OAAK,GAAE;KAAC,IAAI,IAAE,KAAK,QAAQ;AAAG,UAAK,QAAQ,KAAG,MAAK,KAAK,KAAK,OAAO,EAAE,EAAC,KAAK,QAAQ,KAAK,EAAE;;;GAAG,yBAAuB,MAAG;AAAC,WAAK,GAAE,EAAE,IAAE,IAAG,EAAE,IAAE,EAAE,CAAC;;GAAE,wBAAsB,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,QAAQ,IAAI,EAAE,IAAE,EAAE,EAAC,EAAE,IAAE,GAAG,CAAC;AAAC,QAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE;;GAAE,wBAAsB,MAAG;AAAC,WAAK,GAAE,QAAQ,IAAI,EAAE,IAAE,EAAE,EAAC,EAAE,IAAE,GAAG,EAAC,EAAE,IAAE,GAAG,CAAC;;GAAE,2BAAyB,MAAG;AAAC,WAAK,GAAE,QAAQ,eAAe,EAAE,IAAE,EAAE,EAAC,EAAE,IAAE,GAAG,CAAC;;GAAE,0BAAwB,MAAG;AAAC,WAAK,GAAE,EAAE,IAAE,IAAG,QAAQ,IAAI,EAAE,IAAE,EAAE,EAAC,EAAE,IAAE,GAAG,CAAC,CAAC;;GAAE,6BAA2B,MAAG;AAAC,WAAK,GAAE,QAAQ,IAAI,EAAE,IAAE,EAAE,EAAC,EAAE,IAAE,GAAG,EAAC,EAAE,IAAE,GAAG,CAAC;;GAAE,yBAAuB,MAAG;AAAC,WAAK;AAAE,QAAG;KAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,QAAQ,IAAI,GAAE,EAAE,IAAE,GAAG,CAAC,EAAC,IAAE,EAAE,IAAE,GAAG,EAAC,IAAE,QAAQ,MAAM,GAAE,GAAE,EAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;aAAO,GAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;;;GAAG,2BAAyB,MAAG;AAAC,WAAK;AAAE,QAAG;KAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,GAAG,EAAC,IAAE,QAAQ,MAAM,GAAE,KAAK,GAAE,EAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;aAAO,GAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;;;GAAG,wBAAsB,MAAG;AAAC,WAAK;AAAE,QAAG;KAAC,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,GAAG,EAAC,IAAE,QAAQ,UAAU,GAAE,EAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;aAAO,GAAE;AAAC,SAAE,KAAK,MAAM,QAAQ,OAAO,KAAG,GAAE,EAAE,IAAE,IAAG,EAAE,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;;;GAAG,2BAAyB,MAAG;AAAC,WAAK,GAAE,EAAE,IAAE,IAAG,OAAO,SAAS,EAAE,IAAE,EAAE,CAAC,OAAO,CAAC;;GAAE,kCAAgC,MAAG;AAAC,WAAK;IAAE,IAAI,IAAEF,IAAE,OAAO,OAAO,EAAE,IAAE,EAAE,CAAC,CAAC;AAAC,MAAE,IAAE,IAAG,EAAE,EAAC,EAAE,IAAE,IAAG,EAAE,OAAO;;GAAE,+BAA6B,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,EAAE,IAAE,EAAE;AAAC,MAAE,IAAE,GAAG,CAAC,IAAI,EAAE;;GAAE,+BAA6B,MAAG;AAAC,WAAK,GAAE,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE,IAAE,EAAE,YAAW,EAAE,IAAE,GAAG,GAAC,IAAE,EAAE;;GAAE,6BAA2B,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,GAAG;AAAC,QAAG,EAAE,aAAa,cAAY,aAAa,oBAAmB;AAAC,UAAK,IAAI,SAAS,IAAE,IAAG,EAAE;AAAC;;IAAO,IAAI,IAAE,EAAE,SAAS,GAAE,EAAE,OAAO;AAAC,MAAE,IAAI,EAAE,EAAC,EAAE,IAAE,IAAG,EAAE,OAAO,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;;GAAE,6BAA2B,MAAG;AAAC,WAAK;IAAE,IAAI,IAAE,EAAE,IAAE,EAAE,EAAC,IAAE,EAAE,IAAE,GAAG;AAAC,QAAG,EAAE,aAAa,cAAY,aAAa,oBAAmB;AAAC,UAAK,IAAI,SAAS,IAAE,IAAG,EAAE;AAAC;;IAAO,IAAI,IAAE,EAAE,SAAS,GAAE,EAAE,OAAO;AAAC,MAAE,IAAI,EAAE,EAAC,EAAE,IAAE,IAAG,EAAE,OAAO,EAAC,KAAK,IAAI,SAAS,IAAE,IAAG,EAAE;;GAAE,QAAM,MAAG;AAAC,YAAQ,IAAI,EAAE;;GAAE,EAAC;;CAAC,MAAM,IAAI,GAAE;AAAC,MAAG,EAAE,aAAa,YAAY,UAAU,OAAM,IAAI,MAAM,wCAAwC;AAAC,OAAK,QAAM,GAAE,KAAK,MAAI,IAAI,SAAS,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAC,KAAK,UAAQ;GAAC;GAAW;GAAE;GAAK,CAAC;GAAE,CAAC;GAAE;GAAW;GAAK,EAAC,KAAK,eAAa,IAAI,MAAM,KAAK,QAAQ,OAAO,CAAC,KAAK,OAAO,kBAAkB,EAAC,KAAK,OAAK,IAAI,IAAI;GAAC,CAAC,GAAE,EAAE;GAAC,CAAC,MAAK,EAAE;GAAC,CAAC,CAAC,GAAE,EAAE;GAAC,CAAC,CAAC,GAAE,EAAE;GAAC,CAAC,YAAW,EAAE;GAAC,CAAC,MAAK,EAAE;GAAC,CAAC,EAAC,KAAK,UAAQ,EAAE,EAAC,KAAK,SAAO,CAAC;EAAE,IAAI,IAAE,MAAK,KAAE,MAAG;GAAC,IAAI,IAAE,GAAE,IAAEA,IAAE,OAAO,GAAG,EAAE,IAAI;AAAC,UAAO,IAAI,WAAW,KAAK,IAAI,QAAO,GAAE,EAAE,OAAO,CAAC,IAAI,EAAE,EAAC,KAAG,EAAE,QAAO,IAAE,MAAI,MAAI,KAAG,IAAE,IAAE,IAAG;KAAG,IAAE,KAAK,KAAK,QAAO,IAAE,EAAE;AAAC,OAAK,KAAK,SAAQ,MAAG;AAAC,KAAE,KAAK,EAAE,EAAE,CAAC;IAAE,EAAC,EAAE,KAAK,EAAE,EAAC,OAAO,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,SAAQ,MAAG;AAAC,KAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,KAAK,CAAC;IAAE,EAAC,EAAE,KAAK,EAAE;EAAC,IAAI,IAAE;AAAE,IAAE,SAAQ,MAAG;AAAC,QAAK,IAAI,UAAU,GAAE,GAAE,CAAC,EAAE,EAAC,KAAK,IAAI,UAAU,IAAE,GAAE,GAAE,CAAC,EAAE,EAAC,KAAG;IAAG,EAAC,KAAK,MAAM,QAAQ,IAAI,GAAE,EAAE,EAAC,KAAK,UAAQ,KAAK,qBAAqB,EAAC,MAAM,KAAK;;CAAa,UAAS;AAAC,MAAG,KAAK,OAAO,OAAM,IAAI,MAAM,gCAAgC;AAAC,OAAK,MAAM,QAAQ,QAAQ,EAAC,KAAK,UAAQ,KAAK,qBAAqB;;CAAC,iBAAiB,GAAE;EAAC,IAAI,IAAE;AAAK,SAAO,WAAU;GAAC,IAAI,IAAE;IAAC,IAAG;IAAE,MAAK;IAAK,MAAK;IAAU;AAAC,UAAO,EAAE,gBAAc,GAAE,EAAE,SAAS,EAAC,EAAE;;;;;;ACA/0M,IAAI,IAAE,OAAM,GAAE,MAAI,GAAG,CAAC,MAAK,MAAG,EAAE,UAAU,GAAE,EAAE,CAAC,EAAC,IAAE,OAAM,GAAE,MAAI,GAAG,CAAC,MAAK,MAAG,EAAE,MAAM,GAAE,EAAE,CAAC,EAAC,IAAE,OAAM,GAAE,MAAI,GAAG,CAAC,MAAK,MAAG,EAAE,aAAa,GAAE,EAAE,CAAC,EAAC,IAAE,OAAM,MAAG;CAAC,IAAG,EAAC,SAAQ,MAAG,MAAM,OAAO,6CAA6C,OAAO,KAAK,EAAE,CAAC,SAAS,SAAS;AAAI,QAAO;GAAG,GAAE,UAAM;AAAC,KAAE,KAAK,GAAE,WAAW,uBAAqB,KAAK;GAAG,WAAO,MAAI,IAAE,GAAG,CAAC,OAAM,MAAG;AAAC,OAAM,IAAE,KAAK,GAAE;EAAG,GAAE,IAAG,IAAE,OAAM,GAAE,MAAI;CAAC,IAAI;AAAE,QAAO,IAAE,OAAM,YAAS;EAAC,IAAI,IAAE,MAAMK,SAAE,SAAS,EAAE,CAAC,MAAK,MAAG,EAAE,OAAO;AAAC,SAAO,YAAY,YAAY,IAAI,WAAW,EAAE,EAAC,EAAE;KAAI,EAAC;GAAG,IAAE,YAAS;CAAC,IAAI,IAAE,IAAIC,KAAC,EAAC,IAAE,MAAM,EAAEC,cAAE,IAAI,IAAI,iBAAgB,OAAO,KAAK,IAAI,CAAC,EAAC,EAAE,aAAa;AAAC,GAAE,IAAI,EAAE,SAAS;CAAC,IAAI,IAAE,WAAW;AAAqB,QAAM;EAAC,YAAW,GAAE,MAAI,IAAI,SAAQ,MAAG;AAAC,OAAG;AAAC,MAAE,EAAE,UAAU,GAAE,KAAG,EAAE,CAAC,CAAC;YAAO,GAAE;AAAC,UAAM,IAAE,KAAK,GAAE;;IAAI;EAAC,QAAO,GAAE,MAAI,IAAI,SAAQ,MAAG,EAAE,EAAE,MAAM,GAAE,KAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,MAAG;AAAC,SAAM,IAAE,KAAK,GAAE;IAAG,CAAC,MAAK,OAAI;GAAC,GAAG;GAAE,KAAI,KAAK,MAAM,EAAE,IAAI;GAAC,EAAE;EAAC,eAAc,GAAE,MAAI,IAAI,SAAQ,MAAG,EAAE,EAAE,aAAa,GAAE,KAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,MAAG;AAAC,SAAM,IAAE,KAAK,GAAE;IAAG,CAAC,MAAK,OAAI;GAAC,GAAG;GAAE,KAAI,KAAK,MAAM,EAAE,IAAI;GAAC,EAAE;EAAC"}