pycharter 0.0.22__py3-none-any.whl → 0.0.24__py3-none-any.whl

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 (404) hide show
  1. api/main.py +27 -1
  2. api/models/docs.py +68 -0
  3. api/models/evolution.py +117 -0
  4. api/models/tracking.py +111 -0
  5. api/models/validation.py +46 -6
  6. api/routes/v1/__init__.py +14 -1
  7. api/routes/v1/docs.py +187 -0
  8. api/routes/v1/evolution.py +337 -0
  9. api/routes/v1/templates.py +211 -27
  10. api/routes/v1/tracking.py +301 -0
  11. api/routes/v1/validation.py +68 -31
  12. pycharter/__init__.py +268 -58
  13. pycharter/data/templates/contract/template_coercion_rules.yaml +57 -0
  14. pycharter/data/templates/contract/template_contract.yaml +122 -0
  15. pycharter/data/templates/contract/template_metadata.yaml +68 -0
  16. pycharter/data/templates/contract/template_schema.yaml +100 -0
  17. pycharter/data/templates/contract/template_validation_rules.yaml +75 -0
  18. pycharter/data/templates/etl/README.md +224 -0
  19. pycharter/data/templates/etl/extract_cloud_azure.yaml +24 -0
  20. pycharter/data/templates/etl/extract_cloud_gcs.yaml +25 -0
  21. pycharter/data/templates/etl/extract_cloud_s3.yaml +30 -0
  22. pycharter/data/templates/etl/extract_database.yaml +34 -0
  23. pycharter/data/templates/etl/extract_database_ssh.yaml +40 -0
  24. pycharter/data/templates/etl/extract_file_csv.yaml +21 -0
  25. pycharter/data/templates/etl/extract_file_glob.yaml +25 -0
  26. pycharter/data/templates/etl/extract_file_json.yaml +24 -0
  27. pycharter/data/templates/etl/extract_file_parquet.yaml +20 -0
  28. pycharter/data/templates/etl/extract_http_paginated.yaml +79 -0
  29. pycharter/data/templates/etl/extract_http_path_params.yaml +38 -0
  30. pycharter/data/templates/etl/extract_http_simple.yaml +62 -0
  31. pycharter/data/templates/etl/load_cloud_azure.yaml +24 -0
  32. pycharter/data/templates/etl/load_cloud_gcs.yaml +22 -0
  33. pycharter/data/templates/etl/load_cloud_s3.yaml +27 -0
  34. pycharter/data/templates/etl/load_file.yaml +34 -0
  35. pycharter/data/templates/etl/load_insert.yaml +18 -0
  36. pycharter/data/templates/etl/load_postgresql.yaml +39 -0
  37. pycharter/data/templates/etl/load_sqlite.yaml +21 -0
  38. pycharter/data/templates/etl/load_truncate_and_load.yaml +20 -0
  39. pycharter/data/templates/etl/load_upsert.yaml +25 -0
  40. pycharter/data/templates/etl/load_with_dlq.yaml +34 -0
  41. pycharter/data/templates/etl/load_with_ssh_tunnel.yaml +35 -0
  42. pycharter/data/templates/etl/pipeline_http_to_db.yaml +75 -0
  43. pycharter/data/templates/etl/transform_combined.yaml +48 -0
  44. pycharter/data/templates/etl/transform_custom_function.yaml +58 -0
  45. pycharter/data/templates/etl/transform_jsonata.yaml +51 -0
  46. pycharter/data/templates/etl/transform_simple.yaml +59 -0
  47. pycharter/db/schemas/.ipynb_checkpoints/data_contract-checkpoint.py +160 -0
  48. pycharter/docs_generator/__init__.py +43 -0
  49. pycharter/docs_generator/generator.py +465 -0
  50. pycharter/docs_generator/renderers.py +247 -0
  51. pycharter/etl_generator/__init__.py +168 -80
  52. pycharter/etl_generator/builder.py +121 -0
  53. pycharter/etl_generator/config_loader.py +394 -0
  54. pycharter/etl_generator/config_validator.py +418 -0
  55. pycharter/etl_generator/context.py +132 -0
  56. pycharter/etl_generator/expression.py +499 -0
  57. pycharter/etl_generator/extractors/__init__.py +30 -0
  58. pycharter/etl_generator/extractors/base.py +70 -0
  59. pycharter/etl_generator/extractors/cloud_storage.py +530 -0
  60. pycharter/etl_generator/extractors/database.py +221 -0
  61. pycharter/etl_generator/extractors/factory.py +185 -0
  62. pycharter/etl_generator/extractors/file.py +475 -0
  63. pycharter/etl_generator/extractors/http.py +895 -0
  64. pycharter/etl_generator/extractors/streaming.py +57 -0
  65. pycharter/etl_generator/loaders/__init__.py +41 -0
  66. pycharter/etl_generator/loaders/base.py +35 -0
  67. pycharter/etl_generator/loaders/cloud.py +87 -0
  68. pycharter/etl_generator/loaders/cloud_storage_loader.py +275 -0
  69. pycharter/etl_generator/loaders/database.py +274 -0
  70. pycharter/etl_generator/loaders/factory.py +180 -0
  71. pycharter/etl_generator/loaders/file.py +72 -0
  72. pycharter/etl_generator/loaders/file_loader.py +130 -0
  73. pycharter/etl_generator/pipeline.py +743 -0
  74. pycharter/etl_generator/protocols.py +54 -0
  75. pycharter/etl_generator/result.py +63 -0
  76. pycharter/etl_generator/schemas/__init__.py +49 -0
  77. pycharter/etl_generator/transformers/__init__.py +49 -0
  78. pycharter/etl_generator/transformers/base.py +63 -0
  79. pycharter/etl_generator/transformers/config.py +45 -0
  80. pycharter/etl_generator/transformers/custom_function.py +101 -0
  81. pycharter/etl_generator/transformers/jsonata_transformer.py +56 -0
  82. pycharter/etl_generator/transformers/operations.py +218 -0
  83. pycharter/etl_generator/transformers/pipeline.py +54 -0
  84. pycharter/etl_generator/transformers/simple_operations.py +131 -0
  85. pycharter/quality/__init__.py +25 -0
  86. pycharter/quality/tracking/__init__.py +64 -0
  87. pycharter/quality/tracking/collector.py +318 -0
  88. pycharter/quality/tracking/exporters.py +238 -0
  89. pycharter/quality/tracking/models.py +194 -0
  90. pycharter/quality/tracking/store.py +385 -0
  91. pycharter/runtime_validator/__init__.py +20 -7
  92. pycharter/runtime_validator/builder.py +328 -0
  93. pycharter/runtime_validator/validator.py +311 -7
  94. pycharter/runtime_validator/validator_core.py +61 -0
  95. pycharter/schema_evolution/__init__.py +61 -0
  96. pycharter/schema_evolution/compatibility.py +270 -0
  97. pycharter/schema_evolution/diff.py +496 -0
  98. pycharter/schema_evolution/models.py +201 -0
  99. pycharter/shared/__init__.py +56 -0
  100. pycharter/shared/errors.py +296 -0
  101. pycharter/shared/protocols.py +234 -0
  102. {pycharter-0.0.22.dist-info → pycharter-0.0.24.dist-info}/METADATA +146 -26
  103. pycharter-0.0.24.dist-info/RECORD +543 -0
  104. {pycharter-0.0.22.dist-info → pycharter-0.0.24.dist-info}/WHEEL +1 -1
  105. ui/static/404/index.html +1 -1
  106. ui/static/404.html +1 -1
  107. ui/static/__next.__PAGE__.txt +1 -1
  108. ui/static/__next._full.txt +1 -1
  109. ui/static/__next._head.txt +1 -1
  110. ui/static/__next._index.txt +1 -1
  111. ui/static/__next._tree.txt +1 -1
  112. ui/static/_next/static/chunks/26dfc590f7714c03.js +1 -0
  113. ui/static/_next/static/chunks/34d289e6db2ef551.js +1 -0
  114. ui/static/_next/static/chunks/99508d9d5869cc27.js +1 -0
  115. ui/static/_next/static/chunks/b313c35a6ba76574.js +1 -0
  116. ui/static/_not-found/__next._full.txt +1 -1
  117. ui/static/_not-found/__next._head.txt +1 -1
  118. ui/static/_not-found/__next._index.txt +1 -1
  119. ui/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
  120. ui/static/_not-found/__next._not-found.txt +1 -1
  121. ui/static/_not-found/__next._tree.txt +1 -1
  122. ui/static/_not-found/index.html +1 -1
  123. ui/static/_not-found/index.txt +1 -1
  124. ui/static/contracts/__next._full.txt +2 -2
  125. ui/static/contracts/__next._head.txt +1 -1
  126. ui/static/contracts/__next._index.txt +1 -1
  127. ui/static/contracts/__next._tree.txt +1 -1
  128. ui/static/contracts/__next.contracts.__PAGE__.txt +2 -2
  129. ui/static/contracts/__next.contracts.txt +1 -1
  130. ui/static/contracts/index.html +1 -1
  131. ui/static/contracts/index.txt +2 -2
  132. ui/static/documentation/__next._full.txt +1 -1
  133. ui/static/documentation/__next._head.txt +1 -1
  134. ui/static/documentation/__next._index.txt +1 -1
  135. ui/static/documentation/__next._tree.txt +1 -1
  136. ui/static/documentation/__next.documentation.__PAGE__.txt +1 -1
  137. ui/static/documentation/__next.documentation.txt +1 -1
  138. ui/static/documentation/index.html +2 -2
  139. ui/static/documentation/index.txt +1 -1
  140. ui/static/index.html +1 -1
  141. ui/static/index.txt +1 -1
  142. ui/static/metadata/__next._full.txt +1 -1
  143. ui/static/metadata/__next._head.txt +1 -1
  144. ui/static/metadata/__next._index.txt +1 -1
  145. ui/static/metadata/__next._tree.txt +1 -1
  146. ui/static/metadata/__next.metadata.__PAGE__.txt +1 -1
  147. ui/static/metadata/__next.metadata.txt +1 -1
  148. ui/static/metadata/index.html +1 -1
  149. ui/static/metadata/index.txt +1 -1
  150. ui/static/quality/__next._full.txt +2 -2
  151. ui/static/quality/__next._head.txt +1 -1
  152. ui/static/quality/__next._index.txt +1 -1
  153. ui/static/quality/__next._tree.txt +1 -1
  154. ui/static/quality/__next.quality.__PAGE__.txt +2 -2
  155. ui/static/quality/__next.quality.txt +1 -1
  156. ui/static/quality/index.html +2 -2
  157. ui/static/quality/index.txt +2 -2
  158. ui/static/rules/__next._full.txt +1 -1
  159. ui/static/rules/__next._head.txt +1 -1
  160. ui/static/rules/__next._index.txt +1 -1
  161. ui/static/rules/__next._tree.txt +1 -1
  162. ui/static/rules/__next.rules.__PAGE__.txt +1 -1
  163. ui/static/rules/__next.rules.txt +1 -1
  164. ui/static/rules/index.html +1 -1
  165. ui/static/rules/index.txt +1 -1
  166. ui/static/schemas/__next._full.txt +1 -1
  167. ui/static/schemas/__next._head.txt +1 -1
  168. ui/static/schemas/__next._index.txt +1 -1
  169. ui/static/schemas/__next._tree.txt +1 -1
  170. ui/static/schemas/__next.schemas.__PAGE__.txt +1 -1
  171. ui/static/schemas/__next.schemas.txt +1 -1
  172. ui/static/schemas/index.html +1 -1
  173. ui/static/schemas/index.txt +1 -1
  174. ui/static/settings/__next._full.txt +1 -1
  175. ui/static/settings/__next._head.txt +1 -1
  176. ui/static/settings/__next._index.txt +1 -1
  177. ui/static/settings/__next._tree.txt +1 -1
  178. ui/static/settings/__next.settings.__PAGE__.txt +1 -1
  179. ui/static/settings/__next.settings.txt +1 -1
  180. ui/static/settings/index.html +1 -1
  181. ui/static/settings/index.txt +1 -1
  182. ui/static/static/404/index.html +1 -1
  183. ui/static/static/404.html +1 -1
  184. ui/static/static/__next.__PAGE__.txt +1 -1
  185. ui/static/static/__next._full.txt +2 -2
  186. ui/static/static/__next._head.txt +1 -1
  187. ui/static/static/__next._index.txt +2 -2
  188. ui/static/static/__next._tree.txt +2 -2
  189. ui/static/static/_next/static/chunks/13d4a0fbd74c1ee4.js +1 -0
  190. ui/static/static/_next/static/chunks/2edb43b48432ac04.js +441 -0
  191. ui/static/static/_next/static/chunks/d2363397e1b2bcab.css +1 -0
  192. ui/static/static/_next/static/chunks/f7d1a90dd75d2572.js +1 -0
  193. ui/static/static/_not-found/__next._full.txt +2 -2
  194. ui/static/static/_not-found/__next._head.txt +1 -1
  195. ui/static/static/_not-found/__next._index.txt +2 -2
  196. ui/static/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
  197. ui/static/static/_not-found/__next._not-found.txt +1 -1
  198. ui/static/static/_not-found/__next._tree.txt +2 -2
  199. ui/static/static/_not-found/index.html +1 -1
  200. ui/static/static/_not-found/index.txt +2 -2
  201. ui/static/static/contracts/__next._full.txt +3 -3
  202. ui/static/static/contracts/__next._head.txt +1 -1
  203. ui/static/static/contracts/__next._index.txt +2 -2
  204. ui/static/static/contracts/__next._tree.txt +2 -2
  205. ui/static/static/contracts/__next.contracts.__PAGE__.txt +2 -2
  206. ui/static/static/contracts/__next.contracts.txt +1 -1
  207. ui/static/static/contracts/index.html +1 -1
  208. ui/static/static/contracts/index.txt +3 -3
  209. ui/static/static/documentation/__next._full.txt +3 -3
  210. ui/static/static/documentation/__next._head.txt +1 -1
  211. ui/static/static/documentation/__next._index.txt +2 -2
  212. ui/static/static/documentation/__next._tree.txt +2 -2
  213. ui/static/static/documentation/__next.documentation.__PAGE__.txt +2 -2
  214. ui/static/static/documentation/__next.documentation.txt +1 -1
  215. ui/static/static/documentation/index.html +2 -2
  216. ui/static/static/documentation/index.txt +3 -3
  217. ui/static/static/index.html +1 -1
  218. ui/static/static/index.txt +2 -2
  219. ui/static/static/metadata/__next._full.txt +2 -2
  220. ui/static/static/metadata/__next._head.txt +1 -1
  221. ui/static/static/metadata/__next._index.txt +2 -2
  222. ui/static/static/metadata/__next._tree.txt +2 -2
  223. ui/static/static/metadata/__next.metadata.__PAGE__.txt +1 -1
  224. ui/static/static/metadata/__next.metadata.txt +1 -1
  225. ui/static/static/metadata/index.html +1 -1
  226. ui/static/static/metadata/index.txt +2 -2
  227. ui/static/static/quality/__next._full.txt +2 -2
  228. ui/static/static/quality/__next._head.txt +1 -1
  229. ui/static/static/quality/__next._index.txt +2 -2
  230. ui/static/static/quality/__next._tree.txt +2 -2
  231. ui/static/static/quality/__next.quality.__PAGE__.txt +1 -1
  232. ui/static/static/quality/__next.quality.txt +1 -1
  233. ui/static/static/quality/index.html +2 -2
  234. ui/static/static/quality/index.txt +2 -2
  235. ui/static/static/rules/__next._full.txt +2 -2
  236. ui/static/static/rules/__next._head.txt +1 -1
  237. ui/static/static/rules/__next._index.txt +2 -2
  238. ui/static/static/rules/__next._tree.txt +2 -2
  239. ui/static/static/rules/__next.rules.__PAGE__.txt +1 -1
  240. ui/static/static/rules/__next.rules.txt +1 -1
  241. ui/static/static/rules/index.html +1 -1
  242. ui/static/static/rules/index.txt +2 -2
  243. ui/static/static/schemas/__next._full.txt +2 -2
  244. ui/static/static/schemas/__next._head.txt +1 -1
  245. ui/static/static/schemas/__next._index.txt +2 -2
  246. ui/static/static/schemas/__next._tree.txt +2 -2
  247. ui/static/static/schemas/__next.schemas.__PAGE__.txt +1 -1
  248. ui/static/static/schemas/__next.schemas.txt +1 -1
  249. ui/static/static/schemas/index.html +1 -1
  250. ui/static/static/schemas/index.txt +2 -2
  251. ui/static/static/settings/__next._full.txt +2 -2
  252. ui/static/static/settings/__next._head.txt +1 -1
  253. ui/static/static/settings/__next._index.txt +2 -2
  254. ui/static/static/settings/__next._tree.txt +2 -2
  255. ui/static/static/settings/__next.settings.__PAGE__.txt +1 -1
  256. ui/static/static/settings/__next.settings.txt +1 -1
  257. ui/static/static/settings/index.html +1 -1
  258. ui/static/static/settings/index.txt +2 -2
  259. ui/static/static/static/.gitkeep +0 -0
  260. ui/static/static/static/404/index.html +1 -0
  261. ui/static/static/static/404.html +1 -0
  262. ui/static/static/static/__next.__PAGE__.txt +10 -0
  263. ui/static/static/static/__next._full.txt +30 -0
  264. ui/static/static/static/__next._head.txt +7 -0
  265. ui/static/static/static/__next._index.txt +9 -0
  266. ui/static/static/static/__next._tree.txt +2 -0
  267. ui/static/static/static/_next/static/chunks/222442f6da32302a.js +1 -0
  268. ui/static/static/static/_next/static/chunks/247eb132b7f7b574.js +1 -0
  269. ui/static/static/static/_next/static/chunks/297d55555b71baba.js +1 -0
  270. ui/static/static/static/_next/static/chunks/2ab439ce003cd691.js +1 -0
  271. ui/static/static/static/_next/static/chunks/414e77373f8ff61c.js +1 -0
  272. ui/static/static/static/_next/static/chunks/49ca65abd26ae49e.js +1 -0
  273. ui/static/static/static/_next/static/chunks/652ad0aa26265c47.js +2 -0
  274. ui/static/static/static/_next/static/chunks/9667e7a3d359eb39.js +1 -0
  275. ui/static/static/static/_next/static/chunks/9c23f44fff36548a.js +1 -0
  276. ui/static/static/static/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  277. ui/static/static/static/_next/static/chunks/b32a0963684b9933.js +4 -0
  278. ui/static/static/static/_next/static/chunks/c69f6cba366bd988.js +1 -0
  279. ui/static/static/static/_next/static/chunks/db913959c675cea6.js +1 -0
  280. ui/static/static/static/_next/static/chunks/f061a4be97bfc3b3.js +1 -0
  281. ui/static/static/static/_next/static/chunks/f2e7afeab1178138.js +1 -0
  282. ui/static/static/static/_next/static/chunks/ff1a16fafef87110.js +1 -0
  283. ui/static/static/static/_next/static/chunks/turbopack-ffcb7ab6794027ef.js +3 -0
  284. ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_buildManifest.js +11 -0
  285. ui/static/static/static/_next/static/tNTkVW6puVXC4bAm4WrHl/_ssgManifest.js +1 -0
  286. ui/static/static/static/_not-found/__next._full.txt +17 -0
  287. ui/static/static/static/_not-found/__next._head.txt +7 -0
  288. ui/static/static/static/_not-found/__next._index.txt +9 -0
  289. ui/static/static/static/_not-found/__next._not-found.__PAGE__.txt +5 -0
  290. ui/static/static/static/_not-found/__next._not-found.txt +4 -0
  291. ui/static/static/static/_not-found/__next._tree.txt +2 -0
  292. ui/static/static/static/_not-found/index.html +1 -0
  293. ui/static/static/static/_not-found/index.txt +17 -0
  294. ui/static/static/static/contracts/__next._full.txt +21 -0
  295. ui/static/static/static/contracts/__next._head.txt +7 -0
  296. ui/static/static/static/contracts/__next._index.txt +9 -0
  297. ui/static/static/static/contracts/__next._tree.txt +2 -0
  298. ui/static/static/static/contracts/__next.contracts.__PAGE__.txt +9 -0
  299. ui/static/static/static/contracts/__next.contracts.txt +4 -0
  300. ui/static/static/static/contracts/index.html +1 -0
  301. ui/static/static/static/contracts/index.txt +21 -0
  302. ui/static/static/static/documentation/__next._full.txt +21 -0
  303. ui/static/static/static/documentation/__next._head.txt +7 -0
  304. ui/static/static/static/documentation/__next._index.txt +9 -0
  305. ui/static/static/static/documentation/__next._tree.txt +2 -0
  306. ui/static/static/static/documentation/__next.documentation.__PAGE__.txt +9 -0
  307. ui/static/static/static/documentation/__next.documentation.txt +4 -0
  308. ui/static/static/static/documentation/index.html +93 -0
  309. ui/static/static/static/documentation/index.txt +21 -0
  310. ui/static/static/static/index.html +1 -0
  311. ui/static/static/static/index.txt +30 -0
  312. ui/static/static/static/metadata/__next._full.txt +21 -0
  313. ui/static/static/static/metadata/__next._head.txt +7 -0
  314. ui/static/static/static/metadata/__next._index.txt +9 -0
  315. ui/static/static/static/metadata/__next._tree.txt +2 -0
  316. ui/static/static/static/metadata/__next.metadata.__PAGE__.txt +9 -0
  317. ui/static/static/static/metadata/__next.metadata.txt +4 -0
  318. ui/static/static/static/metadata/index.html +1 -0
  319. ui/static/static/static/metadata/index.txt +21 -0
  320. ui/static/static/static/quality/__next._full.txt +21 -0
  321. ui/static/static/static/quality/__next._head.txt +7 -0
  322. ui/static/static/static/quality/__next._index.txt +9 -0
  323. ui/static/static/static/quality/__next._tree.txt +2 -0
  324. ui/static/static/static/quality/__next.quality.__PAGE__.txt +9 -0
  325. ui/static/static/static/quality/__next.quality.txt +4 -0
  326. ui/static/static/static/quality/index.html +2 -0
  327. ui/static/static/static/quality/index.txt +21 -0
  328. ui/static/static/static/rules/__next._full.txt +21 -0
  329. ui/static/static/static/rules/__next._head.txt +7 -0
  330. ui/static/static/static/rules/__next._index.txt +9 -0
  331. ui/static/static/static/rules/__next._tree.txt +2 -0
  332. ui/static/static/static/rules/__next.rules.__PAGE__.txt +9 -0
  333. ui/static/static/static/rules/__next.rules.txt +4 -0
  334. ui/static/static/static/rules/index.html +1 -0
  335. ui/static/static/static/rules/index.txt +21 -0
  336. ui/static/static/static/schemas/__next._full.txt +21 -0
  337. ui/static/static/static/schemas/__next._head.txt +7 -0
  338. ui/static/static/static/schemas/__next._index.txt +9 -0
  339. ui/static/static/static/schemas/__next._tree.txt +2 -0
  340. ui/static/static/static/schemas/__next.schemas.__PAGE__.txt +9 -0
  341. ui/static/static/static/schemas/__next.schemas.txt +4 -0
  342. ui/static/static/static/schemas/index.html +1 -0
  343. ui/static/static/static/schemas/index.txt +21 -0
  344. ui/static/static/static/settings/__next._full.txt +21 -0
  345. ui/static/static/static/settings/__next._head.txt +7 -0
  346. ui/static/static/static/settings/__next._index.txt +9 -0
  347. ui/static/static/static/settings/__next._tree.txt +2 -0
  348. ui/static/static/static/settings/__next.settings.__PAGE__.txt +9 -0
  349. ui/static/static/static/settings/__next.settings.txt +4 -0
  350. ui/static/static/static/settings/index.html +1 -0
  351. ui/static/static/static/settings/index.txt +21 -0
  352. ui/static/static/static/validation/__next._full.txt +21 -0
  353. ui/static/static/static/validation/__next._head.txt +7 -0
  354. ui/static/static/static/validation/__next._index.txt +9 -0
  355. ui/static/static/static/validation/__next._tree.txt +2 -0
  356. ui/static/static/static/validation/__next.validation.__PAGE__.txt +9 -0
  357. ui/static/static/static/validation/__next.validation.txt +4 -0
  358. ui/static/static/static/validation/index.html +1 -0
  359. ui/static/static/static/validation/index.txt +21 -0
  360. ui/static/static/validation/__next._full.txt +2 -2
  361. ui/static/static/validation/__next._head.txt +1 -1
  362. ui/static/static/validation/__next._index.txt +2 -2
  363. ui/static/static/validation/__next._tree.txt +2 -2
  364. ui/static/static/validation/__next.validation.__PAGE__.txt +1 -1
  365. ui/static/static/validation/__next.validation.txt +1 -1
  366. ui/static/static/validation/index.html +1 -1
  367. ui/static/static/validation/index.txt +2 -2
  368. ui/static/validation/__next._full.txt +2 -2
  369. ui/static/validation/__next._head.txt +1 -1
  370. ui/static/validation/__next._index.txt +1 -1
  371. ui/static/validation/__next._tree.txt +1 -1
  372. ui/static/validation/__next.validation.__PAGE__.txt +2 -2
  373. ui/static/validation/__next.validation.txt +1 -1
  374. ui/static/validation/index.html +1 -1
  375. ui/static/validation/index.txt +2 -2
  376. pycharter/data/templates/template_coercion_rules.yaml +0 -15
  377. pycharter/data/templates/template_contract.yaml +0 -587
  378. pycharter/data/templates/template_metadata.yaml +0 -38
  379. pycharter/data/templates/template_schema.yaml +0 -22
  380. pycharter/data/templates/template_transform_advanced.yaml +0 -50
  381. pycharter/data/templates/template_transform_simple.yaml +0 -59
  382. pycharter/data/templates/template_validation_rules.yaml +0 -29
  383. pycharter/etl_generator/extraction.py +0 -916
  384. pycharter/etl_generator/factory.py +0 -174
  385. pycharter/etl_generator/orchestrator.py +0 -1650
  386. pycharter/integrations/__init__.py +0 -19
  387. pycharter/integrations/kafka.py +0 -178
  388. pycharter/integrations/streaming.py +0 -100
  389. pycharter-0.0.22.dist-info/RECORD +0 -358
  390. {pycharter-0.0.22.dist-info → pycharter-0.0.24.dist-info}/entry_points.txt +0 -0
  391. {pycharter-0.0.22.dist-info → pycharter-0.0.24.dist-info}/licenses/LICENSE +0 -0
  392. {pycharter-0.0.22.dist-info → pycharter-0.0.24.dist-info}/top_level.txt +0 -0
  393. /ui/static/_next/static/{0rYA78L88aUyD2Uh38hhX → 2gKjNv6YvE6BcIdFthBLs}/_buildManifest.js +0 -0
  394. /ui/static/_next/static/{0rYA78L88aUyD2Uh38hhX → 2gKjNv6YvE6BcIdFthBLs}/_ssgManifest.js +0 -0
  395. /ui/static/static/_next/static/{tNTkVW6puVXC4bAm4WrHl → 0rYA78L88aUyD2Uh38hhX}/_buildManifest.js +0 -0
  396. /ui/static/static/_next/static/{tNTkVW6puVXC4bAm4WrHl → 0rYA78L88aUyD2Uh38hhX}/_ssgManifest.js +0 -0
  397. /ui/static/{_next → static/_next}/static/chunks/c4fa4f4114b7c352.js +0 -0
  398. /ui/static/static/{_next → static/_next}/static/chunks/4e310fe5005770a3.css +0 -0
  399. /ui/static/{_next → static/static/_next}/static/chunks/5e04d10c4a7b58a3.js +0 -0
  400. /ui/static/static/{_next → static/_next}/static/chunks/5fc14c00a2779dc5.js +0 -0
  401. /ui/static/{_next → static/static/_next}/static/chunks/75d88a058d8ffaa6.js +0 -0
  402. /ui/static/{_next → static/static/_next}/static/chunks/8c89634cf6bad76f.js +0 -0
  403. /ui/static/static/{_next → static/_next}/static/chunks/b584574fdc8ab13e.js +0 -0
  404. /ui/static/static/{_next → static/_next}/static/chunks/d5989c94d3614b3a.js +0 -0
@@ -0,0 +1,441 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,33558,e=>{"use strict";var t=e.i(43476),a=e.i(71645),i=e.i(19455),r=e.i(61246),o=e.i(75254);let s=(0,o.default)("Play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]]),n=(0,o.default)("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]),l=(0,o.default)("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);var d=e.i(78583),c=e.i(58041);let m=(0,o.default)("Code",[["polyline",{points:"16 18 22 12 16 6",key:"z7tu5w"}],["polyline",{points:"8 6 2 12 8 18",key:"1eg1df"}]]),p=(0,o.default)("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);var u=e.i(42009);e.i(80428);var h=e.i(50398);let _=[{id:"parse_contract",title:"Contract Parser",description:"Read and decompose data contract files",method:"parse_contract(contract_dict, validate=True)",apiEndpoint:"/api/v1/contracts/parse",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},metadata:{title:"User Contract",version:"1.0.0"}}},exampleCode:`from pycharter import parse_contract, parse_contract_file
2
+
3
+ parse_contract(contract_dict)
4
+ parse_contract_file(file_path)`,arguments:[{name:"contract_data",type:"Dict[str, Any]",description:"Contract data as dictionary containing schema, metadata, ownership, governance_rules, coercion_rules, and validation_rules",required:!0},{name:"validate",type:"bool",description:"If True (default), validate contract against schema before parsing",required:!1,default:"True"}],returns:{type:"ContractMetadata",description:"ContractMetadata object with decomposed components (schema, metadata, ownership, governance_rules, coercion_rules, validation_rules) and version tracking"}},{id:"parse_contract_file",title:"Contract Parser - From File",description:"Parse a data contract from an uploaded file (YAML or JSON)",method:"parse_contract_file(file_path, validate=True)",apiEndpoint:"/api/v1/contracts/parse/upload",apiMethod:"POST",exampleRequest:null,exampleCode:`from pycharter import parse_contract_file
5
+
6
+ # Parse contract from file
7
+ contract_metadata = parse_contract_file("contract.yaml")
8
+ # or
9
+ contract_metadata = parse_contract_file("contract.json", validate=True)`,arguments:[{name:"file_path",type:"str",description:"Path to contract file (YAML or JSON)",required:!0},{name:"validate",type:"bool",description:"If True (default), validate contract against schema before parsing",required:!1,default:"True"}],returns:{type:"ContractMetadata",description:"ContractMetadata object with decomposed components (schema, metadata, ownership, governance_rules, coercion_rules, validation_rules)"}},{id:"build_contract",title:"Contract Builder",description:"Construct consolidated contracts from separate artifacts",method:"build_contract(artifacts: ContractArtifacts, include_metadata=True, include_ownership=True, include_governance=True)",apiEndpoint:"/api/v1/contracts/build",apiMethod:"POST",exampleRequest:{artifacts:{schema:{type:"object",version:"1.0.0",properties:{name:{type:"string"},age:{type:"integer"}}},coercion_rules:{version:"1.0.0",age:"coerce_to_integer"},validation_rules:{version:"1.0.0",age:{greater_than_or_equal_to:{threshold:0}}},metadata:{version:"1.0.0",description:"User contract"}},include_metadata:!0,include_ownership:!0,include_governance:!0},exampleCode:`from pycharter import build_contract, ContractArtifacts
10
+
11
+ artifacts = ContractArtifacts(
12
+ schema={"type": "object", "version": "1.0.0", "properties": {...}},
13
+ coercion_rules={"version": "1.0.0", "age": "coerce_to_integer"},
14
+ validation_rules={"version": "1.0.0", "age": {...}},
15
+ metadata={"version": "1.0.0", "description": "User contract"}
16
+ )
17
+ contract = build_contract(artifacts)`,arguments:[{name:"artifacts",type:"ContractArtifacts",description:"ContractArtifacts dataclass containing schema (required), coercion_rules (optional), validation_rules (optional), and metadata (optional)",required:!0},{name:"include_metadata",type:"bool",description:"Whether to include metadata in the contract",required:!1,default:"True"},{name:"include_ownership",type:"bool",description:"Whether to include ownership information",required:!1,default:"True"},{name:"include_governance",type:"bool",description:"Whether to include governance rules",required:!1,default:"True"}],returns:{type:"Dict[str, Any]",description:"Consolidated contract dictionary ready for runtime validation, containing schema (with merged coercion/validation rules), coercion_rules, validation_rules, metadata (if included), and versions tracking dictionary"}},{id:"build_contract_from_store",title:"Contract Builder - From Store",description:"Build a consolidated contract from artifacts stored in metadata store with individual version control for each component",method:"build_contract_from_store(store, schema_title, schema_version=None, coercion_rules_title=None, coercion_rules_version=None, validation_rules_title=None, validation_rules_version=None, metadata_title=None, metadata_version=None)",apiEndpoint:"/api/v1/contracts/build",apiMethod:"POST",exampleRequest:{schema_title:"user_schema",schema_version:"1.0.0",coercion_rules_title:"user_schema",coercion_rules_version:"1.0.0",validation_rules_title:"user_schema",validation_rules_version:"1.0.0",metadata_title:"user_schema",metadata_version:"1.0.0"},exampleCode:`from pycharter import build_contract_from_store
18
+
19
+ store = PostgresMetadataStore(connection_string)
20
+ store.connect()
21
+ contract = build_contract_from_store(
22
+ store=store,
23
+ schema_title="user_schema",
24
+ schema_version="1.0.0",
25
+ coercion_rules_title="user_schema",
26
+ coercion_rules_version="1.0.0",
27
+ validation_rules_title="user_schema",
28
+ validation_rules_version="1.0.0",
29
+ metadata_title="user_schema",
30
+ metadata_version="1.0.0"
31
+ )`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance connected to the metadata store",required:!0},{name:"schema_title",type:"str",description:"Schema title/identifier",required:!0},{name:"schema_version",type:"Optional[str]",description:"Optional schema version (if None, uses latest version)",required:!1,default:"None"},{name:"coercion_rules_title",type:"Optional[str]",description:"Optional coercion rules title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"coercion_rules_version",type:"Optional[str]",description:"Optional coercion rules version (if None, uses latest version or schema_version)",required:!1,default:"None"},{name:"validation_rules_title",type:"Optional[str]",description:"Optional validation rules title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"validation_rules_version",type:"Optional[str]",description:"Optional validation rules version (if None, uses latest version or schema_version)",required:!1,default:"None"},{name:"metadata_title",type:"Optional[str]",description:"Optional metadata title/identifier (if None, uses schema_title)",required:!1,default:"None"},{name:"metadata_version",type:"Optional[str]",description:"Optional metadata version (if None, uses latest version or schema_version)",required:!1,default:"None"}],returns:{type:"Dict[str, Any]",description:"Consolidated contract dictionary ready for runtime validation, containing schema (with merged coercion/validation rules), coercion_rules, validation_rules, metadata (if included), and versions tracking dictionary"}},{id:"store_schema",title:"Metadata Store - Store Schema",description:"Store a JSON Schema in the metadata store",method:"store.store_schema(schema_name, schema, version)",apiEndpoint:"/api/v1/metadata/schemas",apiMethod:"POST",exampleRequest:{schema_name:"user_schema",schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},version:"1.0.0"},exampleCode:`from pycharter import MetadataStoreClient
32
+
33
+ store = MetadataStoreClient(database_url)
34
+ store.store_schema(schema_id, schema, version)
35
+ store.get_schema(schema_id, version)
36
+ store.store_metadata(schema_id, metadata, version)`,arguments:[{name:"schema_name",type:"str",description:"Name/identifier for the schema (used as data_contract name)",required:!0},{name:"schema",type:"Dict[str, Any]",description:'JSON Schema dictionary (must contain "version" field or it will be added)',required:!0},{name:"version",type:"str",description:'Required version string (must match schema["version"] if present)',required:!0}],returns:{type:"str",description:"Schema ID or identifier"}},{id:"get_schema",title:"Metadata Store - Get Schema",description:"Retrieve a schema from the metadata store",method:"store.get_schema(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/schemas/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import MetadataStoreClient
37
+
38
+ store = MetadataStoreClient(database_url)
39
+ store.get_schema(schema_id, version)`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, returns latest version)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Schema dictionary with version included, or None if not found"}},{id:"list_schemas",title:"Metadata Store - List Schemas",description:"Retrieve a list of all schemas stored in the metadata store",method:"store.list_schemas()",apiEndpoint:"/api/v1/metadata/schemas",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
40
+
41
+ store = PostgresMetadataStore(connection_string)
42
+ store.connect()
43
+
44
+ # List all schemas
45
+ schemas = store.list_schemas()
46
+ for schema in schemas:
47
+ print(f"Schema: {schema.get('name')}, Version: {schema.get('version')}")`,arguments:[],returns:{type:"List[Dict[str, Any]]",description:"List of schema metadata dictionaries, each containing id, name, title, and version"}},{id:"store_metadata",title:"Metadata Store - Store Metadata",description:"Store metadata (ownership, governance rules, etc.) for a schema",method:"store.store_metadata(schema_id, metadata, version=None)",apiEndpoint:"/api/v1/metadata/metadata",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",metadata:{title:"user_schema_metadata",description:"Metadata for user schema",business_owners:["owner@example.com"],team:"data-engineering",governance_rules:{data_retention:{days:2555},access_control:{level:"public"}}},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
48
+
49
+ store = PostgresMetadataStore(connection_string)
50
+ store.connect()
51
+
52
+ # Store metadata for a schema
53
+ metadata_id = store.store_metadata(
54
+ schema_id='user_schema',
55
+ metadata={
56
+ 'title': 'user_schema_metadata',
57
+ 'description': 'Metadata for user schema',
58
+ 'business_owners': ['owner@example.com'],
59
+ 'team': 'data-engineering',
60
+ 'governance_rules': {
61
+ 'data_retention': {'days': 2555},
62
+ 'access_control': {'level': 'public'}
63
+ }
64
+ },
65
+ version='1.0.0'
66
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"metadata",type:"Dict[str, Any]",description:"Metadata dictionary containing ownership, governance_rules, and other metadata",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Metadata record ID"}},{id:"get_metadata",title:"Metadata Store - Get Metadata",description:"Retrieve metadata for a schema from the metadata store",method:"store.get_metadata(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/metadata/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
67
+
68
+ store = PostgresMetadataStore(connection_string)
69
+ store.connect()
70
+
71
+ # Get metadata for a schema
72
+ metadata = store.get_metadata(
73
+ schema_id='user_schema',
74
+ version='1.0.0' # Optional, defaults to latest
75
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses latest version)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Metadata dictionary or None if not found"}},{id:"get_complete_schema",title:"Metadata Store - Get Complete Schema",description:"Retrieve a complete schema with coercion and validation rules merged",method:"store.get_complete_schema(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/schemas/{schema_id}/complete",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
76
+
77
+ store = PostgresMetadataStore(connection_string)
78
+ store.connect()
79
+
80
+ # Get complete schema with rules merged
81
+ complete_schema = store.get_complete_schema(
82
+ schema_id='user_schema',
83
+ version='1.0.0' # Optional, defaults to latest
84
+ )
85
+ # The schema now includes coercion and validation rules
86
+ # merged into the properties`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Complete schema dictionary with coercion and validation rules merged into the properties, or None if not found"}},{id:"store_coercion_rules",title:"Metadata Store - Store Coercion Rules",description:"Store coercion rules that define how data should be transformed before validation",method:"store.store_coercion_rules(schema_id, coercion_rules, version=None)",apiEndpoint:"/api/v1/metadata/coercion-rules",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",coercion_rules:{age:"coerce_to_integer",email:"coerce_to_lowercase",price:"coerce_to_float",name:"coerce_to_stripped_string"},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
87
+
88
+ store = PostgresMetadataStore(connection_string)
89
+ store.connect()
90
+
91
+ # Store coercion rules for a schema
92
+ rule_id = store.store_coercion_rules(
93
+ schema_id='user_schema',
94
+ coercion_rules={
95
+ 'age': 'coerce_to_integer',
96
+ 'email': 'coerce_to_lowercase',
97
+ 'name': 'coerce_to_stripped_string'
98
+ },
99
+ version='1.0.0'
100
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"coercion_rules",type:"Dict[str, Any]",description:'Dictionary mapping field names to coercion rule types (e.g., "coerce_to_integer", "coerce_to_lowercase")',required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Coercion rule record ID"}},{id:"get_coercion_rules",title:"Metadata Store - Get Coercion Rules",description:"Retrieve coercion rules for a schema from the metadata store",method:"store.get_coercion_rules(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/coercion-rules/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
101
+
102
+ store = PostgresMetadataStore(connection_string)
103
+ store.connect()
104
+
105
+ # Get coercion rules for a schema
106
+ coercion_rules = store.get_coercion_rules(
107
+ schema_id='user_schema',
108
+ version='1.0.0' # Optional, defaults to latest
109
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Coercion rules dictionary mapping field names to coercion types, or None if not found"}},{id:"store_validation_rules",title:"Metadata Store - Store Validation Rules",description:"Store validation rules that define custom validation logic beyond JSON Schema",method:"store.store_validation_rules(schema_id, validation_rules, version=None)",apiEndpoint:"/api/v1/metadata/validation-rules",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",validation_rules:{age:{greater_than_or_equal_to:{threshold:0},less_than_or_equal_to:{threshold:150}},email:{min_length:{threshold:5},matches_pattern:{pattern:"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"}}},version:"1.0.0"},exampleCode:`from pycharter import PostgresMetadataStore
110
+
111
+ store = PostgresMetadataStore(connection_string)
112
+ store.connect()
113
+
114
+ # Store validation rules for a schema
115
+ rule_id = store.store_validation_rules(
116
+ schema_id='user_schema',
117
+ validation_rules={
118
+ 'age': {
119
+ 'greater_than_or_equal_to': {'threshold': 0},
120
+ 'less_than_or_equal_to': {'threshold': 150}
121
+ },
122
+ 'email': {
123
+ 'min_length': {'threshold': 5},
124
+ 'matches_pattern': {'pattern': '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'}
125
+ }
126
+ },
127
+ version='1.0.0'
128
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"validation_rules",type:"Dict[str, Any]",description:'Dictionary mapping field names to validation rule dictionaries (e.g., {"age": {"greater_than_or_equal_to": {"threshold": 0}}})',required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, uses schema version)",required:!1,default:"None"}],returns:{type:"str",description:"Validation rule record ID"}},{id:"get_validation_rules",title:"Metadata Store - Get Validation Rules",description:"Retrieve validation rules for a schema from the metadata store",method:"store.get_validation_rules(schema_id, version=None)",apiEndpoint:"/api/v1/metadata/validation-rules/{schema_id}",apiMethod:"GET",exampleRequest:null,exampleCode:`from pycharter import PostgresMetadataStore
129
+
130
+ store = PostgresMetadataStore(connection_string)
131
+ store.connect()
132
+
133
+ # Get validation rules for a schema
134
+ validation_rules = store.get_validation_rules(
135
+ schema_id='user_schema',
136
+ version='1.0.0' # Optional, defaults to latest
137
+ )`,arguments:[{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional version string (if None, defaults to latest)",required:!1,default:"None"}],returns:{type:"Optional[Dict[str, Any]]",description:"Validation rules dictionary mapping field names to validation rule dictionaries, or None if not found"}},{id:"generate_model",title:"Pydantic Generator",description:"Generate Pydantic models from JSON Schema",method:'generate_model(schema, model_name="DynamicModel")',apiEndpoint:"/api/v1/schemas/generate",apiMethod:"POST",exampleRequest:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}},model_name:"User"},exampleCode:`from pycharter import generate_model, generate_model_file, from_dict, from_file, from_json, from_url
138
+
139
+ # Advanced: More control
140
+ UserModel = generate_model(schema_dict, model_name="User")
141
+
142
+ # Quick helpers: Generate and return model
143
+ UserModel = from_dict(schema_dict) # From dictionary
144
+ UserModel = from_file("schema.json") # From file
145
+ UserModel = from_json(json_string) # From JSON string
146
+ UserModel = from_url("https://example.com/schema.json") # From URL
147
+
148
+ # Generate model and save to file
149
+ generate_model_file(schema_dict, "models.py", model_name="User")`,arguments:[{name:"schema",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0},{name:"model_name",type:"str",description:"Name for the generated Pydantic model class",required:!1,default:'"DynamicModel"'}],returns:{type:"Type[BaseModel]",description:"A Pydantic model class generated from the schema"}},{id:"from_dict",title:"Generate Model from Dict",description:"Quick helper: Generate Pydantic model from JSON Schema dictionary",method:"from_dict(schema_dict)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_dict
150
+
151
+ schema = {
152
+ "type": "object",
153
+ "properties": {
154
+ "name": {"type": "string"},
155
+ "age": {"type": "integer"}
156
+ }
157
+ }
158
+
159
+ UserModel = from_dict(schema)
160
+ user = UserModel(name="Alice", age=30)`,arguments:[{name:"schema_dict",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema"}},{id:"from_file",title:"Generate Model from File",description:"Quick helper: Generate Pydantic model from JSON Schema file",method:"from_file(file_path)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_file
161
+
162
+ UserModel = from_file("schema.json")
163
+ # or
164
+ UserModel = from_file("schema.yaml")`,arguments:[{name:"file_path",type:"str",description:"Path to JSON Schema file (JSON or YAML)",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema file"}},{id:"from_json",title:"Generate Model from JSON String",description:"Quick helper: Generate Pydantic model from JSON Schema JSON string",method:"from_json(json_string)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_json
165
+
166
+ json_schema = '{"type": "object", "properties": {"name": {"type": "string"}}}'
167
+ UserModel = from_json(json_schema)`,arguments:[{name:"json_string",type:"str",description:"JSON Schema as JSON string",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the JSON string"}},{id:"from_url",title:"Generate Model from URL",description:"Quick helper: Generate Pydantic model from JSON Schema URL",method:"from_url(url)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import from_url
168
+
169
+ UserModel = from_url("https://example.com/schema.json")`,arguments:[{name:"url",type:"str",description:"URL to JSON Schema file",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the URL"}},{id:"generate_model_file",title:"Generate Model File",description:"Generate Pydantic model and save to Python file",method:'generate_model_file(schema, output_file, model_name="DynamicModel")',apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import generate_model_file
170
+
171
+ schema = {
172
+ "type": "object",
173
+ "properties": {
174
+ "name": {"type": "string"},
175
+ "age": {"type": "integer"}
176
+ }
177
+ }
178
+
179
+ generate_model_file(
180
+ schema=schema,
181
+ output_file="models.py",
182
+ model_name="User"
183
+ )`,arguments:[{name:"schema",type:"Dict[str, Any]",description:"JSON Schema dictionary",required:!0},{name:"output_file",type:"str",description:"Path to output Python file",required:!0},{name:"model_name",type:"str",description:"Name for the generated Pydantic model class",required:!1,default:'"DynamicModel"'}],returns:{type:"None",description:"Saves the generated model to the specified file"}},{id:"model_to_schema",title:"JSON Schema Converter (Advanced)",description:"Convert Pydantic models to JSON Schema - core conversion function",method:"model_to_schema(model_class)",apiEndpoint:"/api/v1/schemas/convert",apiMethod:"POST",exampleRequest:{model_class:"pydantic.BaseModel"},exampleCode:`from pycharter import model_to_schema
184
+ from pydantic import BaseModel
185
+
186
+ class UserModel(BaseModel):
187
+ name: str
188
+ age: int
189
+
190
+ schema = model_to_schema(UserModel)
191
+ print(schema)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:'Pydantic model class or fully qualified class name (e.g., "mymodule.UserModel")',required:!0}],returns:{type:"Dict[str, Any]",description:"JSON Schema dictionary with optional title and version fields"}},{id:"to_dict",title:"Convert Model to Dict",description:"Quick helper: Convert Pydantic model to JSON Schema dictionary",method:"to_dict(model_class)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_dict
192
+ from pydantic import BaseModel
193
+
194
+ class UserModel(BaseModel):
195
+ name: str
196
+ age: int
197
+
198
+ schema = to_dict(UserModel)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0}],returns:{type:"Dict[str, Any]",description:"JSON Schema dictionary"}},{id:"to_json",title:"Convert Model to JSON String",description:"Quick helper: Convert Pydantic model to JSON Schema JSON string",method:"to_json(model_class)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_json
199
+ from pydantic import BaseModel
200
+
201
+ class UserModel(BaseModel):
202
+ name: str
203
+ age: int
204
+
205
+ json_schema = to_json(UserModel)
206
+ print(json_schema)`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0}],returns:{type:"str",description:"JSON Schema as JSON string"}},{id:"to_file",title:"Convert Model to File",description:"Quick helper: Convert Pydantic model to JSON Schema file",method:"to_file(model_class, file_path)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import to_file
207
+ from pydantic import BaseModel
208
+
209
+ class UserModel(BaseModel):
210
+ name: str
211
+ age: int
212
+
213
+ to_file(UserModel, "schema.json")
214
+ # or
215
+ to_file(UserModel, "schema.yaml")`,arguments:[{name:"model_class",type:"Type[BaseModel] | str",description:"Pydantic model class or fully qualified class name",required:!0},{name:"file_path",type:"str",description:"Path to output file (JSON or YAML)",required:!0}],returns:{type:"None",description:"Saves the JSON Schema to the specified file"}},{id:"validator_class",title:"Validator Class (PRIMARY INTERFACE)",description:"⭐ PRIMARY: Use Validator class for all validation - best performance and flexibility",method:"Validator(contract_dir=None, contract_file=None, contract_dict=None, contract_metadata=None, store=None, schema_id=None, schema_version=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import Validator, create_validator
216
+ from pycharter.metadata_store import SQLiteMetadataStore
217
+
218
+ # From contract directory
219
+ validator = Validator(contract_dir="data/contracts/user")
220
+ result = validator.validate({"name": "Alice", "age": 30})
221
+
222
+ # From metadata store
223
+ store = SQLiteMetadataStore("metadata.db")
224
+ store.connect()
225
+ validator = Validator(store=store, schema_id="user_schema")
226
+ result = validator.validate({"name": "Alice", "age": 30})
227
+
228
+ # From contract file
229
+ validator = Validator(contract_file="contracts/user.yaml")
230
+ result = validator.validate({"name": "Alice", "age": 30})
231
+
232
+ # Batch validation
233
+ results = validator.validate_batch([
234
+ {"name": "Alice", "age": 30},
235
+ {"name": "Bob", "age": 25}
236
+ ])
237
+
238
+ # Factory function
239
+ validator = create_validator(contract_file="contract.yaml")`,arguments:[{name:"contract_dir",type:"Optional[str]",description:"Directory containing contract files (schema.yaml, coercion_rules.yaml, validation_rules.yaml)",required:!1},{name:"contract_file",type:"Optional[str]",description:"Path to complete contract file (YAML/JSON)",required:!1},{name:"contract_dict",type:"Optional[Dict[str, Any]]",description:"Contract as dictionary with schema, coercion_rules, validation_rules keys",required:!1},{name:"contract_metadata",type:"Optional[ContractMetadata]",description:"ContractMetadata object (from parse_contract)",required:!1},{name:"store",type:"Optional[MetadataStoreClient]",description:"MetadataStoreClient instance (for loading from metadata store)",required:!1},{name:"schema_id",type:"Optional[str]",description:"Schema identifier (required when using store)",required:!1},{name:"schema_version",type:"Optional[str]",description:"Optional schema version (defaults to latest when using store)",required:!1}],returns:{type:"Validator",description:"Validator instance with validate() and validate_batch() methods"}},{id:"validate_with_store",title:"Validate with Store (Convenience)",description:"Quick validation using schema from metadata store",method:"validate_with_store(store, schema_id, data, version=None, strict=False)",apiEndpoint:"/api/v1/validation/validate",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data:{name:"Alice",age:30},version:"1.0.0",strict:!1},exampleCode:`from pycharter import validate_with_store
240
+ from pycharter.metadata_store import SQLiteMetadataStore
241
+
242
+ store = SQLiteMetadataStore("metadata.db")
243
+ store.connect()
244
+
245
+ result = validate_with_store(
246
+ store=store,
247
+ schema_id="user_schema",
248
+ data={"name": "Alice", "age": 30},
249
+ version="1.0.0"
250
+ )
251
+
252
+ if result.is_valid:
253
+ print("Valid data:", result.data)
254
+ else:
255
+ print("Errors:", result.errors)`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_with_contract",title:"Validate with Contract (Convenience)",description:"Quick validation using contract dictionary or file",method:"validate_with_contract(contract, data, strict=False)",apiEndpoint:"/api/v1/validation/validate",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}}},data:{name:"Alice",age:30},strict:!1},exampleCode:`from pycharter import validate_with_contract
256
+
257
+ contract = {
258
+ "schema": {
259
+ "type": "object",
260
+ "properties": {
261
+ "name": {"type": "string"},
262
+ "age": {"type": "integer"}
263
+ }
264
+ }
265
+ }
266
+
267
+ result = validate_with_contract(
268
+ contract=contract,
269
+ data={"name": "Alice", "age": 30}
270
+ )
271
+
272
+ # Or from file
273
+ result = validate_with_contract(
274
+ contract="contracts/user.yaml",
275
+ data={"name": "Alice", "age": 30}
276
+ )`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0},{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_batch_with_store",title:"Batch Validate with Store",description:"Validate multiple records using schema from metadata store",method:"validate_batch_with_store(store, schema_id, data_list, version=None, strict=False)",apiEndpoint:"/api/v1/validation/validate-batch",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data_list:[{name:"Alice",age:30},{name:"Bob",age:25}],version:"1.0.0",strict:!1},exampleCode:`from pycharter import validate_batch_with_store
277
+ from pycharter.metadata_store import SQLiteMetadataStore
278
+
279
+ store = SQLiteMetadataStore("metadata.db")
280
+ store.connect()
281
+
282
+ results = validate_batch_with_store(
283
+ store=store,
284
+ schema_id="user_schema",
285
+ data_list=[
286
+ {"name": "Alice", "age": 30},
287
+ {"name": "Bob", "age": 25}
288
+ ],
289
+ version="1.0.0"
290
+ )
291
+
292
+ print(f"Valid: {results.total_count - len(results.errors)}/{results.total_count}")`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"validate_batch_with_contract",title:"Batch Validate with Contract",description:"Validate multiple records using contract dictionary or file",method:"validate_batch_with_contract(contract, data_list, strict=False)",apiEndpoint:"/api/v1/validation/validate-batch",apiMethod:"POST",exampleRequest:{contract:{schema:{type:"object",properties:{name:{type:"string"},age:{type:"integer"}}}},data_list:[{name:"Alice",age:30},{name:"Bob",age:25}],strict:!1},exampleCode:`from pycharter import validate_batch_with_contract
293
+
294
+ contract = {
295
+ "schema": {
296
+ "type": "object",
297
+ "properties": {
298
+ "name": {"type": "string"},
299
+ "age": {"type": "integer"}
300
+ }
301
+ }
302
+ }
303
+
304
+ results = validate_batch_with_contract(
305
+ contract=contract,
306
+ data_list=[
307
+ {"name": "Alice", "age": 30},
308
+ {"name": "Bob", "age": 25}
309
+ ]
310
+ )`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0},{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"get_model_from_store",title:"Get Model from Store",description:"Get Pydantic model class from schema stored in metadata store",method:"get_model_from_store(store, schema_id, version=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import get_model_from_store
311
+ from pycharter.metadata_store import SQLiteMetadataStore
312
+
313
+ store = SQLiteMetadataStore("metadata.db")
314
+ store.connect()
315
+
316
+ # Get Pydantic model class
317
+ UserModel = get_model_from_store(
318
+ store=store,
319
+ schema_id="user_schema",
320
+ version="1.0.0"
321
+ )
322
+
323
+ # Use the model directly
324
+ user = UserModel(name="Alice", age=30)
325
+ print(user.model_dump())`,arguments:[{name:"store",type:"MetadataStoreClient",description:"MetadataStoreClient instance",required:!0},{name:"schema_id",type:"str",description:"Schema identifier",required:!0},{name:"version",type:"Optional[str]",description:"Optional schema version (if None, uses latest)",required:!1,default:"None"}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the schema"}},{id:"get_model_from_contract",title:"Get Model from Contract",description:"Get Pydantic model class from contract dictionary or file",method:"get_model_from_contract(contract)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import get_model_from_contract
326
+
327
+ contract = {
328
+ "schema": {
329
+ "type": "object",
330
+ "properties": {
331
+ "name": {"type": "string"},
332
+ "age": {"type": "integer"}
333
+ }
334
+ }
335
+ }
336
+
337
+ # Get Pydantic model class
338
+ UserModel = get_model_from_contract(contract)
339
+
340
+ # Use the model directly
341
+ user = UserModel(name="Alice", age=30)
342
+ print(user.model_dump())
343
+
344
+ # Or from file
345
+ UserModel = get_model_from_contract("contracts/user.yaml")`,arguments:[{name:"contract",type:"Dict[str, Any] | ContractMetadata | str",description:"Contract dictionary, ContractMetadata object, or file path",required:!0}],returns:{type:"Type[BaseModel]",description:"Pydantic model class generated from the contract schema"}},{id:"validate",title:"Validate (Low-level)",description:"Low-level validation with existing Pydantic model",method:"validate(data, model, coercion_rules=None, validation_rules=None, strict=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import validate
346
+ from pydantic import BaseModel
347
+
348
+ # Define model manually or get from contract
349
+ class UserModel(BaseModel):
350
+ name: str
351
+ age: int
352
+
353
+ # Validate with model
354
+ result = validate(
355
+ data={"name": "Alice", "age": 30},
356
+ model=UserModel,
357
+ coercion_rules=None,
358
+ validation_rules=None
359
+ )
360
+
361
+ if result.is_valid:
362
+ print("Valid:", result.data)
363
+ else:
364
+ print("Errors:", result.errors)`,arguments:[{name:"data",type:"Dict[str, Any]",description:"Data dictionary to validate",required:!0},{name:"model",type:"Type[BaseModel]",description:"Pydantic model class",required:!0},{name:"coercion_rules",type:"Optional[Dict[str, Any]]",description:"Optional coercion rules dictionary",required:!1,default:"None"},{name:"validation_rules",type:"Optional[Dict[str, Any]]",description:"Optional validation rules dictionary",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationResult",description:"ValidationResult object with is_valid flag, validated data (if valid), and list of errors (if invalid)"}},{id:"validate_batch",title:"Batch Validate (Low-level)",description:"Low-level batch validation with existing Pydantic model",method:"validate_batch(data_list, model, coercion_rules=None, validation_rules=None, strict=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import validate_batch
365
+ from pydantic import BaseModel
366
+
367
+ # Define model manually or get from contract
368
+ class UserModel(BaseModel):
369
+ name: str
370
+ age: int
371
+
372
+ # Batch validate with model
373
+ results = validate_batch(
374
+ data_list=[
375
+ {"name": "Alice", "age": 30},
376
+ {"name": "Bob", "age": 25}
377
+ ],
378
+ model=UserModel
379
+ )
380
+
381
+ print(f"Valid: {results.valid_count}/{results.total_count}")`,arguments:[{name:"data_list",type:"List[Dict[str, Any]]",description:"List of data dictionaries to validate",required:!0},{name:"model",type:"Type[BaseModel]",description:"Pydantic model class",required:!0},{name:"coercion_rules",type:"Optional[Dict[str, Any]]",description:"Optional coercion rules dictionary",required:!1,default:"None"},{name:"validation_rules",type:"Optional[Dict[str, Any]]",description:"Optional validation rules dictionary",required:!1,default:"None"},{name:"strict",type:"bool",description:"If True, raise exceptions on validation errors",required:!1,default:"False"}],returns:{type:"ValidationBatchResponse",description:"Batch validation results with total_count, valid_count, error_count, and results list"}},{id:"quality_check",title:"QualityCheck Class (PRIMARY INTERFACE)",description:"⭐ PRIMARY: Use QualityCheck class for quality assurance - monitor data quality, calculate metrics, and track violations",method:"QualityCheck(store=None, db_session=None).run(schema_id=None, contract=None, data=None, options=None)",apiEndpoint:"/api/v1/quality/check",apiMethod:"POST",exampleRequest:{schema_id:"user_schema",data:[{name:"Alice",age:30},{name:"Bob",age:25}],calculate_metrics:!0,record_violations:!0},exampleCode:`from pycharter import QualityCheck, QualityCheckOptions, QualityReport, QualityThresholds
382
+ from pycharter.metadata_store import SQLiteMetadataStore
383
+ from sqlalchemy.orm import Session
384
+
385
+ # Create quality check instance
386
+ store = SQLiteMetadataStore("metadata.db")
387
+ store.connect()
388
+ db_session = Session() # Your database session
389
+
390
+ check = QualityCheck(store=store, db_session=db_session)
391
+
392
+ # Configure options
393
+ options = QualityCheckOptions(
394
+ record_violations=True,
395
+ calculate_metrics=True,
396
+ check_thresholds=True,
397
+ include_field_metrics=True,
398
+ sample_size=None # Process all data
399
+ )
400
+
401
+ # Set thresholds (optional)
402
+ thresholds = QualityThresholds(
403
+ overall_score_min=80.0,
404
+ accuracy_min=95.0,
405
+ completeness_min=90.0
406
+ )
407
+
408
+ # Run quality check
409
+ report = check.run(
410
+ schema_id='user_schema',
411
+ data="data/users.json", # File path, list, or callable
412
+ options=options
413
+ )
414
+
415
+ # Access results
416
+ print(f"Quality Score: {report.quality_score.overall_score:.2f}/100")
417
+ print(f"Passed: {report.passed}")
418
+ print(f"Metrics: {report.metrics}")
419
+ print(f"Violations: {len(report.violations)}")`,arguments:[{name:"store",type:"Optional[MetadataStoreClient]",description:"Optional metadata store for retrieving contracts and storing violations",required:!1,default:"None"},{name:"db_session",type:"Optional[Session]",description:"Optional SQLAlchemy database session for persisting metrics and violations",required:!1,default:"None"},{name:"schema_id",type:"Optional[str]",description:"Schema ID (if using store-based validation)",required:!1},{name:"contract",type:"Optional[Dict[str, Any] | str]",description:"Contract dictionary or file path (if using contract-based validation)",required:!1},{name:"data",type:"List[Dict[str, Any]] | str | Callable",description:"Data to validate. Can be a list of dictionaries, file path (JSON/CSV), or callable that returns data",required:!0},{name:"options",type:"Optional[QualityCheckOptions]",description:"Quality check options including record_violations, calculate_metrics, check_thresholds, include_field_metrics, sample_size, data_source, data_version, etc.",required:!1,default:"None"}],returns:{type:"QualityReport",description:"QualityReport object containing validation results, quality score (QualityScore), field metrics (FieldQualityMetrics), violations (List[ViolationRecord]), and threshold breaches"}},{id:"quality_check_options",title:"QualityCheckOptions",description:"Configuration options for quality checks",method:"QualityCheckOptions(record_violations=True, calculate_metrics=True, check_thresholds=False, include_field_metrics=True, sample_size=None, data_source=None, data_version=None, skip_if_unchanged=False)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import QualityCheckOptions
420
+
421
+ options = QualityCheckOptions(
422
+ record_violations=True, # Record violations to database
423
+ calculate_metrics=True, # Calculate quality metrics
424
+ check_thresholds=False, # Check against quality thresholds
425
+ include_field_metrics=True, # Include field-level metrics
426
+ sample_size=1000, # Sample size for large datasets
427
+ data_source="users.csv", # Data source identifier
428
+ data_version="v1.0", # Data version identifier
429
+ skip_if_unchanged=True # Skip if data hasn't changed
430
+ )`,arguments:[{name:"record_violations",type:"bool",description:"Whether to record violations to database",required:!1,default:"True"},{name:"calculate_metrics",type:"bool",description:"Whether to calculate quality metrics",required:!1,default:"True"},{name:"check_thresholds",type:"bool",description:"Whether to check against quality thresholds",required:!1,default:"False"},{name:"include_field_metrics",type:"bool",description:"Whether to include field-level quality metrics",required:!1,default:"True"},{name:"sample_size",type:"Optional[int]",description:"Sample size for large datasets (None = process all)",required:!1,default:"None"},{name:"data_source",type:"Optional[str]",description:"Data source identifier (e.g., file name)",required:!1,default:"None"},{name:"data_version",type:"Optional[str]",description:"Data version identifier",required:!1,default:"None"},{name:"skip_if_unchanged",type:"bool",description:"Skip quality check if data fingerprint hasn't changed",required:!1,default:"False"}],returns:{type:"QualityCheckOptions",description:"QualityCheckOptions instance for configuring quality checks"}},{id:"quality_thresholds",title:"QualityThresholds",description:"Define quality thresholds for monitoring and alerting",method:"QualityThresholds(overall_score_min=None, accuracy_min=None, completeness_min=None, violation_rate_max=None, field_thresholds=None)",apiEndpoint:null,apiMethod:"N/A",exampleRequest:null,exampleCode:`from pycharter import QualityThresholds
431
+
432
+ thresholds = QualityThresholds(
433
+ overall_score_min=80.0, # Minimum overall quality score
434
+ accuracy_min=95.0, # Minimum accuracy percentage
435
+ completeness_min=90.0, # Minimum completeness percentage
436
+ violation_rate_max=0.05, # Maximum violation rate (5%)
437
+ field_thresholds={ # Field-specific thresholds
438
+ "email": {"completeness_min": 98.0},
439
+ "age": {"accuracy_min": 99.0}
440
+ }
441
+ )`,arguments:[{name:"overall_score_min",type:"Optional[float]",description:"Minimum overall quality score (0-100)",required:!1,default:"None"},{name:"accuracy_min",type:"Optional[float]",description:"Minimum accuracy percentage (0-100)",required:!1,default:"None"},{name:"completeness_min",type:"Optional[float]",description:"Minimum completeness percentage (0-100)",required:!1,default:"None"},{name:"violation_rate_max",type:"Optional[float]",description:"Maximum violation rate (0-1)",required:!1,default:"None"},{name:"field_thresholds",type:"Optional[Dict[str, Dict[str, float]]]",description:'Field-specific thresholds (e.g., {"email": {"completeness_min": 98.0}})',required:!1,default:"None"}],returns:{type:"QualityThresholds",description:"QualityThresholds instance for defining quality requirements"}}];function f({method:o}){let[d,c]=(0,a.useState)(o.exampleRequest?JSON.stringify(o.exampleRequest,null,2):""),[m,p]=(0,a.useState)(null),[u,h]=(0,a.useState)(null),[_,f]=(0,a.useState)(!1),[y,v]=(0,a.useState)(!1);if(!o.apiEndpoint)return null;let g=o.apiEndpoint?.includes("/upload")??!1,x=async()=>{f(!0),h(null);try{let t,a,{getApiBaseUrl:i}=await e.A(36909),r=i(),s=o.apiEndpoint;if(!s){h({success:!1,error:"This method does not have an API endpoint (Python-only)"}),f(!1);return}s.includes("{schema_id}")&&(s=s.replace("{schema_id}","user_schema"));let n=`${r}${s}`;if("GET"===o.apiMethod)t=await fetch(n);else if(g){if(!m){h({success:!1,error:"Please select a file to upload"}),f(!1);return}let e=new FormData;e.append("file",m),s.includes("/contracts/parse/upload")&&e.append("validate","true"),t=await fetch(n,{method:o.apiMethod,body:e})}else{let e=d?JSON.parse(d):{};t=await fetch(n,{method:o.apiMethod,headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}let l=t.headers.get("content-type");a=l&&l.includes("application/json")?await t.json():{message:await t.text()},t.ok?h({success:!0,data:a}):h({success:!1,error:a.detail||a.message||`HTTP ${t.status}: ${t.statusText}`})}catch(t){let e=t.message;e.includes("JSON")&&(e="Invalid JSON in request body. Please check your input."),h({success:!1,error:e||"Failed to test API"})}finally{f(!1)}};return(0,t.jsxs)("div",{className:"border rounded-lg p-4 bg-muted/30",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold",children:"Test API"}),o.apiEndpoint&&(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(i.Button,{size:"sm",variant:"outline",onClick:()=>{var e;return o.apiEndpoint&&(e=o.apiEndpoint,void(navigator.clipboard.writeText(e),v(!0),setTimeout(()=>v(!1),2e3)))},className:"h-7",disabled:!o.apiEndpoint,children:y?(0,t.jsx)(l,{className:"h-3 w-3"}):(0,t.jsx)(n,{className:"h-3 w-3"})}),(0,t.jsx)(i.Button,{size:"sm",onClick:x,disabled:_||"GET"!==o.apiMethod&&!g&&!d||g&&!m,className:"h-7",children:_?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"mr-1",children:(0,t.jsx)(r.default,{size:"sm"})}),"Testing..."]}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s,{className:"h-3 w-3 mr-1"}),"Test"]})})]})]}),o.apiEndpoint&&"GET"!==o.apiMethod&&(0,t.jsx)("div",{className:"mb-3",children:g?(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium mb-1",children:"Upload File"}),(0,t.jsx)("input",{type:"file",accept:".yaml,.yml,.json",onChange:e=>p(e.target.files?.[0]||null),className:"w-full px-2 py-1 border rounded text-xs bg-background"}),m&&(0,t.jsxs)("div",{className:"mt-1 text-xs text-muted-foreground",children:["Selected: ",m.name," (",(m.size/1024).toFixed(2)," KB)"]})]}):(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"block text-xs font-medium mb-1",children:"Request Body (JSON)"}),(0,t.jsx)("textarea",{value:d,onChange:e=>c(e.target.value),rows:6,className:"w-full px-2 py-1 border rounded text-xs font-mono bg-background",placeholder:"Enter JSON request body..."})]})}),o.apiEndpoint&&(0,t.jsxs)("div",{className:"text-xs text-muted-foreground mb-2",children:[(0,t.jsx)("span",{className:"font-mono font-semibold",children:o.apiMethod})," ",o.apiEndpoint]}),u&&(0,t.jsx)("div",{className:"mt-3",children:u.success?(0,t.jsxs)("div",{className:"bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded p-2",children:[(0,t.jsx)("div",{className:"text-xs font-semibold text-green-800 dark:text-green-200 mb-1",children:"Success"}),(0,t.jsx)("pre",{className:"text-xs overflow-x-auto text-green-700 dark:text-green-300",children:JSON.stringify(u.data,null,2)})]}):(0,t.jsxs)("div",{className:"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded p-2",children:[(0,t.jsx)("div",{className:"text-xs font-semibold text-red-800 dark:text-red-200 mb-1",children:"Error"}),(0,t.jsx)("div",{className:"text-xs text-red-700 dark:text-red-300",children:u.error})]})})]})}function y(){let[e,i]=(0,a.useState)("contract-management"),r={"contract-management":["parse_contract","parse_contract_file","build_contract","build_contract_from_store"],"metadata-store":["store_schema","get_schema","list_schemas","store_metadata","get_metadata","store_coercion_rules","get_coercion_rules","store_validation_rules","get_validation_rules","get_complete_schema"],"model-generator":["generate_model","generate_model_file","from_dict","from_file","from_json","from_url","model_to_schema","to_dict","to_json","to_file"],validation:["validator_class","validate_with_store","validate_with_contract","validate_batch_with_store","validate_batch_with_contract","get_model_from_store","get_model_from_contract","validate","validate_batch"],"quality-assurance":["quality_check","quality_check_options","quality_thresholds"]},o=e=>{let t=Object.keys(r).find(t=>r[t].includes(e));if(t)i(t),setTimeout(()=>{let t=document.getElementById(`method-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})},150);else{let t=document.getElementById(`method-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})}},s=[{id:"contract-management",title:"Contract Management",icon:d.FileText,items:[{id:"parse_contract",label:"Parse Contract",onClick:()=>o("parse_contract")},{id:"build_contract",label:"Build Contract",onClick:()=>o("build_contract")}]},{id:"metadata-store",title:"Metadata Store Client",icon:c.Database,items:[{id:"store_schema",label:"Store Schema",onClick:()=>o("store_schema")},{id:"get_schema",label:"Get Schema",onClick:()=>o("get_schema")},{id:"list_schemas",label:"List Schemas",onClick:()=>o("list_schemas")},{id:"store_metadata",label:"Store Metadata",onClick:()=>o("store_metadata")},{id:"get_metadata",label:"Get Metadata",onClick:()=>o("get_metadata")},{id:"store_coercion_rules",label:"Store Coercion Rules",onClick:()=>o("store_coercion_rules")},{id:"get_coercion_rules",label:"Get Coercion Rules",onClick:()=>o("get_coercion_rules")},{id:"store_validation_rules",label:"Store Validation Rules",onClick:()=>o("store_validation_rules")},{id:"get_validation_rules",label:"Get Validation Rules",onClick:()=>o("get_validation_rules")},{id:"get_complete_schema",label:"Get Complete Schema",onClick:()=>o("get_complete_schema")}]},{id:"model-generator",title:"Model Generator",icon:m,items:[{id:"generate_model",label:"Generate Model",onClick:()=>o("generate_model")},{id:"generate_model_file",label:"Generate Model File",onClick:()=>o("generate_model_file")},{id:"from_dict",label:"From Dict",onClick:()=>o("from_dict")},{id:"from_file",label:"From File",onClick:()=>o("from_file")},{id:"from_json",label:"From JSON",onClick:()=>o("from_json")},{id:"from_url",label:"From URL",onClick:()=>o("from_url")},{id:"model_to_schema",label:"Model to Schema",onClick:()=>o("model_to_schema")},{id:"to_dict",label:"To Dict",onClick:()=>o("to_dict")},{id:"to_json",label:"To JSON",onClick:()=>o("to_json")},{id:"to_file",label:"To File",onClick:()=>o("to_file")}]},{id:"validation",title:"Validation",icon:p,items:[{id:"validator_class",label:"⭐ Validator Class",onClick:()=>o("validator_class")},{id:"validate_with_store",label:"Validate with Store",onClick:()=>o("validate_with_store")},{id:"validate_with_contract",label:"Validate with Contract",onClick:()=>o("validate_with_contract")},{id:"validate_batch_with_store",label:"Batch Validate (Store)",onClick:()=>o("validate_batch_with_store")},{id:"validate_batch_with_contract",label:"Batch Validate (Contract)",onClick:()=>o("validate_batch_with_contract")},{id:"get_model_from_store",label:"Get Model (Store)",onClick:()=>o("get_model_from_store")},{id:"get_model_from_contract",label:"Get Model (Contract)",onClick:()=>o("get_model_from_contract")},{id:"validate",label:"Validate (Low-level)",onClick:()=>o("validate")},{id:"validate_batch",label:"Batch Validate (Low-level)",onClick:()=>o("validate_batch")}]},{id:"quality-assurance",title:"Quality Assurance",icon:u.Award,items:[{id:"quality_check",label:"⭐ QualityCheck Class",onClick:()=>o("quality_check")},{id:"quality_check_options",label:"QualityCheckOptions",onClick:()=>o("quality_check_options")},{id:"quality_thresholds",label:"QualityThresholds",onClick:()=>o("quality_thresholds")}]}],n=r[e]?_.filter(t=>r[e].includes(t.id)):_;return(0,t.jsxs)("div",{className:"flex h-full bg-background",style:{height:"calc(100vh - 4rem)",overflow:"hidden"},children:[(0,t.jsx)("div",{className:"flex-shrink-0",style:{height:"100%",overflow:"hidden"},children:(0,t.jsx)(h.CollapsibleSidebar,{sections:s,defaultCollapsed:!1,headerTitle:"Documentation",selectedSection:e,onSectionClick:e=>{i(e),setTimeout(()=>{let t=document.getElementById(`section-${e}`);t&&t.scrollIntoView({behavior:"smooth",block:"start"})},100)}})}),(0,t.jsx)("div",{className:"flex-1 min-w-0",style:{height:"100%",overflowY:"auto",overflowX:"hidden"},"data-content-area":!0,children:(0,t.jsx)("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:(0,t.jsxs)("div",{className:"space-y-8",children:[(0,t.jsxs)("div",{id:`section-${e}`,className:"scroll-mt-4 mb-4",children:[(0,t.jsx)("h2",{className:"text-2xl font-bold text-foreground mb-1",children:s.find(t=>t.id===e)?.title||"Documentation"}),(0,t.jsxs)("p",{className:"text-sm text-muted-foreground",children:["contract-management"===e&&"Manage and work with data contracts","metadata-store"===e&&"Store and retrieve schemas, metadata, coercion rules, and validation rules","model-generator"===e&&"Generate Pydantic models from schemas","validation"===e&&"Validate data against schemas and contracts","quality-assurance"===e&&"Monitor data quality and track violations"]})]}),(0,t.jsx)("div",{className:"space-y-6",children:n.map(e=>(0,t.jsx)("div",{id:`method-${e.id}`,className:"border rounded-lg overflow-hidden scroll-mt-4",children:(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4 p-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"font-semibold mb-2",children:e.title}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground mb-3",children:e.description}),e.arguments&&e.arguments.length>0&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold mb-2",children:"Arguments"}),(0,t.jsx)("div",{className:"space-y-2",children:e.arguments.map((e,a)=>(0,t.jsxs)("div",{className:"text-xs border-l-2 border-primary/20 pl-2",children:[(0,t.jsxs)("div",{className:"font-mono font-semibold text-foreground",children:[e.name,!e.required&&(0,t.jsx)("span",{className:"text-muted-foreground ml-1",children:"(optional)"})]}),(0,t.jsxs)("div",{className:"text-muted-foreground mt-0.5",children:[(0,t.jsx)("span",{className:"font-mono",children:e.type}),e.default&&(0,t.jsxs)("span",{className:"ml-1",children:["default: ",e.default]})]}),(0,t.jsx)("div",{className:"text-muted-foreground mt-1",children:e.description})]},a))})]}),e.returns&&(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)("h5",{className:"text-sm font-semibold mb-2",children:"Returns"}),(0,t.jsxs)("div",{className:"text-xs border-l-2 border-green-500/20 pl-2",children:[(0,t.jsx)("div",{className:"font-mono font-semibold text-foreground mb-0.5",children:e.returns.type}),(0,t.jsx)("div",{className:"text-muted-foreground",children:e.returns.description})]})]}),(0,t.jsx)("div",{className:"bg-muted p-3 rounded font-mono text-xs overflow-x-auto mb-3",children:(0,t.jsx)("pre",{className:"whitespace-pre-wrap",children:e.exampleCode})}),(0,t.jsxs)("div",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-semibold",children:"Method:"})," ",e.method]})]}),(0,t.jsx)("div",{children:(0,t.jsx)(f,{method:e})})]})},e.id))}),(0,t.jsxs)("div",{className:"border rounded-lg p-4 bg-primary/5",children:[(0,t.jsx)("h4",{className:"font-semibold mb-2",children:"Additional Resources"}),(0,t.jsxs)("ul",{className:"text-sm space-y-1 text-muted-foreground",children:[(0,t.jsx)("li",{children:"• Full documentation: See README.md and REFERENCE.md"}),(0,t.jsx)("li",{children:"• Examples: Check the examples/ directory"}),(0,t.jsx)("li",{children:"• API Documentation: Available at /docs when running the API server"})]})]})]})})})]})}e.s(["default",()=>y],33558)}]);
@@ -0,0 +1 @@
1
+ *,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:221.2 83.2% 53.3%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:221.2 83.2% 53.3%;--radius:.5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.right-0{right:0}.top-0{top:0}.z-50{z-index:50}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-16{height:4rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.max-h-\[90vh\]{max-height:90vh}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-10{width:2.5rem}.w-11{width:2.75rem}.w-12{width:3rem}.w-16{width:4rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-3\/4{width:75%}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-5\/6{width:83.3333%}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-md{max-width:28rem}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.rotate-180{--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:2s cubic-bezier(.4,0,.6,1) infinite pulse}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize{resize:both}.scroll-mt-4{scroll-margin-top:1rem}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem*var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-border>:not([hidden])~:not([hidden]){border-color:hsl(var(--border))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-blue-200{--tw-border-opacity:1;border-color:rgb(191 219 254/var(--tw-border-opacity,1))}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border)/.5)}.border-destructive\/50{border-color:hsl(var(--destructive)/.5)}.border-green-200{--tw-border-opacity:1;border-color:rgb(187 247 208/var(--tw-border-opacity,1))}.border-green-500\/20{border-color:#22c55e33}.border-input{border-color:hsl(var(--input))}.border-muted{border-color:hsl(var(--muted))}.border-primary{border-color:hsl(var(--primary))}.border-primary\/20{border-color:hsl(var(--primary)/.2)}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-transparent{border-color:#0000}.border-t-primary{border-top-color:hsl(var(--primary))}.bg-background{background-color:hsl(var(--background))}.bg-black\/50{background-color:#00000080}.bg-blue-100{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.bg-card{background-color:hsl(var(--card))}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive)/.1)}.bg-destructive\/5{background-color:hsl(var(--destructive)/.05)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-300{--tw-bg-opacity:1;background-color:rgb(209 213 219/var(--tw-bg-opacity,1))}.bg-green-100{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(240 253 244/var(--tw-bg-opacity,1))}.bg-input{background-color:hsl(var(--input))}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/30{background-color:hsl(var(--muted)/.3)}.bg-muted\/50{background-color:hsl(var(--muted)/.5)}.bg-orange-100{--tw-bg-opacity:1;background-color:rgb(255 237 213/var(--tw-bg-opacity,1))}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary)/.1)}.bg-primary\/5{background-color:hsl(var(--primary)/.05)}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-secondary{background-color:hsl(var(--secondary))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-yellow-100{--tw-bg-opacity:1;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))}.p-0{padding:0}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0\.5{padding-bottom:.125rem}.pb-1{padding-bottom:.25rem}.pb-3{padding-bottom:.75rem}.pl-2{padding-left:.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.leading-8{line-height:2rem}.leading-none{line-height:1}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-blue-800{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-destructive\/90{color:hsl(var(--destructive)/.9)}.text-foreground{color:hsl(var(--foreground))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-green-700{--tw-text-opacity:1;color:rgb(21 128 61/var(--tw-text-opacity,1))}.text-green-800{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity,1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-orange-600{--tw-text-opacity:1;color:rgb(234 88 12/var(--tw-text-opacity,1))}.text-orange-800{--tw-text-opacity:1;color:rgb(154 52 18/var(--tw-text-opacity,1))}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-red-800{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity,1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-yellow-600{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity,1))}.text-yellow-800{--tw-text-opacity:1;color:rgb(133 77 14/var(--tw-text-opacity,1))}.underline-offset-4{text-underline-offset:4px}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-75{opacity:.75}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline-offset:2px;outline:2px solid #0000}.outline{outline-style:solid}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1))}.ring-opacity-5{--tw-ring-opacity:.05}.ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-shadow{transition-property:box-shadow;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-property:transform;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.duration-300{animation-duration:.3s}.running{animation-play-state:running}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:hsl(var(--muted))}::-webkit-scrollbar-thumb{background:hsl(var(--muted-foreground)/.3);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:hsl(var(--muted-foreground)/.5)}[data-group]{touch-action:none}[data-separator]{position:relative;touch-action:none!important;-webkit-user-select:none!important;user-select:none!important;cursor:col-resize!important;pointer-events:auto!important}[data-separator]:hover{background-color:hsl(var(--primary)/.5)!important}[data-separator][data-separator-state=dragging]{background-color:hsl(var(--primary))!important}.file\:mr-4::file-selector-button{margin-right:1rem}.file\:rounded-md::file-selector-button{border-radius:calc(var(--radius) - 2px)}.file\:border-0::file-selector-button{border-width:0}.file\:bg-primary::file-selector-button{background-color:hsl(var(--primary))}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:px-4::file-selector-button{padding-left:1rem;padding-right:1rem}.file\:py-2::file-selector-button{padding-top:.5rem;padding-bottom:.5rem}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.file\:font-semibold::file-selector-button{font-weight:600}.file\:text-primary-foreground::file-selector-button{color:hsl(var(--primary-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:left-\[2px\]:after{content:var(--tw-content);left:2px}.after\:top-\[2px\]:after{content:var(--tw-content);top:2px}.after\:h-5:after{content:var(--tw-content);height:1.25rem}.after\:w-5:after{content:var(--tw-content);width:1.25rem}.after\:rounded-full:after{content:var(--tw-content);border-radius:9999px}.after\:border:after{content:var(--tw-content);border-width:1px}.after\:border-gray-300:after{content:var(--tw-content);--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.after\:bg-background:after{content:var(--tw-content);background-color:hsl(var(--background))}.after\:transition-all:after{content:var(--tw-content);transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.hover\:translate-x-0\.5:hover{--tw-translate-x:.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.hover\:border-gray-300:hover{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-blue-500:hover{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive)/.9)}.hover\:bg-muted:hover{background-color:hsl(var(--muted))}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted)/.5)}.hover\:bg-primary\/15:hover{background-color:hsl(var(--primary)/.15)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary)/.9)}.hover\:bg-secondary\/80:hover{background-color:hsl(var(--secondary)/.8)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:shadow-sm:hover{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hover\:file\:bg-primary\/90::file-selector-button:hover{background-color:hsl(var(--primary)/.9)}.focus\:outline-none:focus{outline-offset:2px;outline:2px solid #0000}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-inset:focus{--tw-ring-inset:inset}.focus\:ring-primary:focus{--tw-ring-color:hsl(var(--primary))}.focus\:ring-ring:focus{--tw-ring-color:hsl(var(--ring))}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.focus-visible\:outline-none:focus-visible{outline-offset:2px;outline:2px solid #0000}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.active\:scale-95:active{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.peer:checked~.peer-checked\:bg-primary{background-color:hsl(var(--primary))}.peer:checked~.peer-checked\:after\:translate-x-full:after{content:var(--tw-content);--tw-translate-x:100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.peer:checked~.peer-checked\:after\:border-white:after{content:var(--tw-content);--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity,1))}.peer:focus~.peer-focus\:outline-none{outline-offset:2px;outline:2px solid #0000}.peer:focus~.peer-focus\:ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.peer:focus~.peer-focus\:ring-ring{--tw-ring-color:hsl(var(--ring))}.peer:focus~.peer-focus\:ring-offset-2{--tw-ring-offset-width:2px}.peer:focus~.peer-focus\:ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.peer:disabled~.peer-disabled\:cursor-not-allowed{cursor:not-allowed}.peer:disabled~.peer-disabled\:opacity-70{opacity:.7}.dark\:border-blue-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(30 64 175/var(--tw-border-opacity,1))}.dark\:border-destructive:is(.dark *){border-color:hsl(var(--destructive))}.dark\:border-green-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(22 101 52/var(--tw-border-opacity,1))}.dark\:border-red-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(153 27 27/var(--tw-border-opacity,1))}.dark\:bg-blue-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(30 58 138/var(--tw-bg-opacity,1))}.dark\:bg-blue-950:is(.dark *){--tw-bg-opacity:1;background-color:rgb(23 37 84/var(--tw-bg-opacity,1))}.dark\:bg-gray-800:is(.dark *){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-green-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(20 83 45/var(--tw-bg-opacity,1))}.dark\:bg-green-900\/20:is(.dark *){background-color:#14532d33}.dark\:bg-orange-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(124 45 18/var(--tw-bg-opacity,1))}.dark\:bg-red-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(127 29 29/var(--tw-bg-opacity,1))}.dark\:bg-red-900\/20:is(.dark *){background-color:#7f1d1d33}.dark\:bg-yellow-900:is(.dark *){--tw-bg-opacity:1;background-color:rgb(113 63 18/var(--tw-bg-opacity,1))}.dark\:text-blue-200:is(.dark *){--tw-text-opacity:1;color:rgb(191 219 254/var(--tw-text-opacity,1))}.dark\:text-blue-400:is(.dark *){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.dark\:text-gray-200:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:text-green-200:is(.dark *){--tw-text-opacity:1;color:rgb(187 247 208/var(--tw-text-opacity,1))}.dark\:text-green-300:is(.dark *){--tw-text-opacity:1;color:rgb(134 239 172/var(--tw-text-opacity,1))}.dark\:text-green-400:is(.dark *){--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.dark\:text-orange-200:is(.dark *){--tw-text-opacity:1;color:rgb(254 215 170/var(--tw-text-opacity,1))}.dark\:text-orange-400:is(.dark *){--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.dark\:text-red-200:is(.dark *){--tw-text-opacity:1;color:rgb(254 202 202/var(--tw-text-opacity,1))}.dark\:text-red-300:is(.dark *){--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.dark\:text-red-400:is(.dark *){--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.dark\:text-yellow-200:is(.dark *){--tw-text-opacity:1;color:rgb(254 240 138/var(--tw-text-opacity,1))}.dark\:text-yellow-400:is(.dark *){--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}@media (min-width:640px){.sm\:ml-6{margin-left:1.5rem}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(2rem*var(--tw-space-x-reverse));margin-left:calc(2rem*calc(1 - var(--tw-space-x-reverse)))}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-5xl{font-size:3rem;line-height:1}}@media (min-width:768px){.md\:table-cell{display:table-cell}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:text-6xl{font-size:3.75rem;line-height:1}}@media (min-width:1024px){.lg\:table-cell{display:table-cell}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:table-cell{display:table-cell}}.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div{--tw-translate-y:-3px;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.\[\&\>svg\]\:absolute>svg{position:absolute}.\[\&\>svg\]\:left-4>svg{left:1rem}.\[\&\>svg\]\:top-4>svg{top:1rem}.\[\&\>svg\]\:text-destructive>svg{color:hsl(var(--destructive))}.\[\&\>svg\]\:text-foreground>svg{color:hsl(var(--foreground))}.\[\&\>svg\~\*\]\:pl-7>svg~*{padding-left:1.75rem}.\[\&_p\]\:leading-relaxed p{line-height:1.625}
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,61246,e=>{"use strict";var t=e.i(43476),a=e.i(75157);function s({className:e,...s}){return(0,t.jsx)("div",{className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...s})}function r({size:e="md",className:s}){return(0,t.jsx)("div",{className:(0,a.cn)("flex items-center justify-center",s),children:(0,t.jsx)("div",{className:(0,a.cn)("animate-spin rounded-full border-2 border-muted border-t-primary",{sm:"h-4 w-4",md:"h-8 w-8",lg:"h-12 w-12"}[e])})})}function l({message:e="Loading..."}){return(0,t.jsx)("div",{className:"min-h-screen flex items-center justify-center bg-background",children:(0,t.jsxs)("div",{className:"text-center",children:[(0,t.jsx)(r,{size:"lg",className:"mb-4"}),(0,t.jsx)("p",{className:"text-muted-foreground",children:e})]})})}function d(){return(0,t.jsxs)("div",{className:"rounded-lg border bg-card p-6 space-y-4",children:[(0,t.jsx)(s,{className:"h-6 w-3/4"}),(0,t.jsx)(s,{className:"h-4 w-full"}),(0,t.jsx)(s,{className:"h-4 w-5/6"}),(0,t.jsxs)("div",{className:"flex gap-2 mt-4",children:[(0,t.jsx)(s,{className:"h-9 w-20"}),(0,t.jsx)(s,{className:"h-9 w-20"})]})]})}function i({rows:e=5}){return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)(s,{className:"h-10 w-full"}),Array.from({length:e}).map((e,a)=>(0,t.jsx)(s,{className:"h-12 w-full"},a))]})}e.s(["CardSkeleton",()=>d,"PageLoading",()=>l,"TableSkeleton",()=>i,"default",()=>r],61246)},78583,e=>{"use strict";let t=(0,e.i(75254).default)("FileText",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]]);e.s(["FileText",()=>t],78583)},58041,e=>{"use strict";let t=(0,e.i(75254).default)("Database",[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]]);e.s(["Database",()=>t],58041)},42009,50398,80428,e=>{"use strict";var t=e.i(75254);let a=(0,t.default)("Award",[["path",{d:"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526",key:"1yiouv"}],["circle",{cx:"12",cy:"8",r:"6",key:"1vp47v"}]]);e.s(["Award",()=>a],42009);var s=e.i(43476),r=e.i(71645);let l=(0,t.default)("ChevronLeft",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]),d=(0,t.default)("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);var i=e.i(64659);let n=(0,t.default)("ChevronUp",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);function o({sections:e,defaultCollapsed:t=!1,onItemClick:a,onSectionClick:o,selectedSection:c,headerTitle:m="Navigation"}){let[u,h]=(0,r.useState)(t),[x,f]=(0,r.useState)(new Set(e.map(e=>e.id)));return(0,s.jsxs)("div",{className:`flex flex-col bg-background border-r border-border/50 shadow-sm transition-all duration-300 ${u?"w-16":"w-64"}`,style:{height:"100%",overflow:"hidden"},children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border/50 bg-muted/30",children:[!u&&(0,s.jsx)("h2",{className:"text-sm font-semibold text-foreground tracking-wide",children:m}),(0,s.jsx)("button",{onClick:()=>{h(!u)},className:"p-1.5 rounded-md hover:bg-muted transition-all duration-200 hover:scale-105 active:scale-95","aria-label":u?"Expand sidebar":"Collapse sidebar",children:u?(0,s.jsx)(d,{className:"h-4 w-4 text-muted-foreground"}):(0,s.jsx)(l,{className:"h-4 w-4 text-muted-foreground"})})]}),(0,s.jsx)("div",{className:"flex-1 overflow-y-auto overflow-x-hidden px-2 py-3",style:{maxHeight:"100%"},children:(0,s.jsx)("div",{className:"space-y-1",children:e.map(e=>{let t=x.has(e.id);return(0,s.jsxs)("div",{className:"mb-1",children:[(0,s.jsx)("button",{onClick:()=>{var t;o&&o(e.id),t=e.id,f(e=>{let a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a})},className:`w-full flex items-center justify-between px-3 py-2.5 rounded-lg transition-all duration-200 ${u?"justify-center hover:bg-muted/50":c===e.id?"bg-primary/10 text-primary hover:bg-primary/15":"hover:bg-muted/50 hover:shadow-sm"}`,title:u?e.title:void 0,children:u?e.icon?(0,s.jsx)(e.icon,{className:`h-5 w-5 transition-colors ${c===e.id?"text-primary":"text-muted-foreground"}`}):(0,s.jsx)("span",{className:`text-xs font-semibold ${c===e.id?"text-primary":"text-muted-foreground"}`,children:e.title.charAt(0).toUpperCase()}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex items-center gap-2.5",children:[e.icon&&(0,s.jsx)(e.icon,{className:`h-4 w-4 transition-colors ${c===e.id?"text-primary":"text-muted-foreground"}`}),(0,s.jsx)("span",{className:`text-sm font-medium ${c===e.id?"text-primary":"text-foreground"}`,children:e.title})]}),t?(0,s.jsx)(n,{className:"h-3.5 w-3.5 text-muted-foreground transition-transform duration-200"}):(0,s.jsx)(i.ChevronDown,{className:"h-3.5 w-3.5 text-muted-foreground transition-transform duration-200"})]})}),!u&&t&&(0,s.jsx)("div",{className:"ml-1 mt-1 space-y-0.5 pl-2 border-l-2 border-muted",children:e.items.map(t=>(0,s.jsx)("button",{onClick:()=>{var s,r;return s=e.id,r=t.id,void(t.onClick&&t.onClick(),a&&a(s,r))},className:"w-full text-left px-3 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted/50 rounded-md transition-all duration-200 hover:translate-x-0.5",children:t.label},t.id))})]},e.id)})})})]})}e.s(["CollapsibleSidebar",()=>o],50398),e.s([],80428)},36909,e=>{e.v(t=>Promise.all(["static/chunks/222442f6da32302a.js"].map(t=>e.l(t))).then(()=>t(43668)))}]);