@axzydev/axzy_ui_system 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/index.cjs +1738 -308
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.cts +739 -3
  5. package/dist/index.d.ts +739 -3
  6. package/dist/index.js +1629 -233
  7. package/dist/index.js.map +1 -1
  8. package/dist/layered.css +1 -1
  9. package/package.json +14 -7
  10. package/src/App.tsx +60 -2
  11. package/src/components/atoms/image/image.props.ts +2 -0
  12. package/src/components/atoms/image/image.tsx +3 -2
  13. package/src/components/organisms/dialog/dialog.props.ts +2 -0
  14. package/src/components/organisms/dialog/dialog.tsx +4 -3
  15. package/src/dev.css +6 -0
  16. package/src/index.ts +90 -1
  17. package/src/json-renderer/catalog/axzyCatalog.ts +362 -0
  18. package/src/json-renderer/catalog/catalog.props.ts +128 -0
  19. package/src/json-renderer/catalog/resolve.ts +225 -0
  20. package/src/json-renderer/index.ts +70 -0
  21. package/src/json-renderer/kernel/NodeBoundary.tsx +53 -0
  22. package/src/json-renderer/kernel/SchemaRenderer.tsx +197 -0
  23. package/src/json-renderer/kernel/kernel.test.tsx +341 -0
  24. package/src/json-renderer/kernel/partial.ts +92 -0
  25. package/src/json-renderer/kernel/renderNode.tsx +113 -0
  26. package/src/json-renderer/kernel/schemaRenderer.props.ts +42 -0
  27. package/src/json-renderer/kernel/types.ts +159 -0
  28. package/src/json-renderer/shared/errors.ts +92 -0
  29. package/src/json-renderer/shared/limits.ts +87 -0
  30. package/src/json-renderer/shared/paths.ts +66 -0
  31. package/src/json-renderer/shared/shared.test.ts +108 -0
  32. package/src/json-renderer/stream/tolerantParse.test.ts +152 -0
  33. package/src/json-renderer/stream/tolerantParse.ts +449 -0
  34. package/src/json-renderer/test/setup.ts +38 -0
  35. package/src/json-renderer/validation/migrate.ts +83 -0
  36. package/src/json-renderer/validation/validate.ts +161 -0
  37. package/src/json-renderer/validation/validation.test.ts +165 -0
  38. package/src/json-renderer/vocabulary/buildContract.ts +158 -0
  39. package/src/sandbox/axzyConfig.test.ts +40 -0
  40. package/src/sandbox/axzyConfig.ts +77 -0
  41. package/src/sandbox/i18n.ts +218 -0
  42. package/src/sandbox/navigation.ts +1 -0
  43. package/src/sandbox/useHashRoute.ts +39 -9
  44. package/src/showcases/DemoJsonDashboard.tsx +489 -0
  45. package/src/showcases/DemoJsonDocs.tsx +339 -0
  46. package/src/showcases/DemoJsonPortfolio.tsx +257 -0
  47. package/src/showcases/JsonScreenShowcase.tsx +341 -0
  48. package/src/showcases/demoApp/demoData.ts +181 -0
  49. package/src/showcases/demoApp/nodeTree.test.ts +39 -0
  50. package/src/showcases/demoApp/nodeTree.ts +35 -0
  51. package/src/showcases/demoApp/schemas.test.ts +54 -0
package/dist/index.cjs CHANGED
@@ -31,7 +31,13 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
31
31
  // src/index.ts
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
+ AXZY_CATALOG_ENTRIES: () => AXZY_CATALOG_ENTRIES,
35
+ AXZY_EXCLUDED_TYPES: () => AXZY_EXCLUDED_TYPES,
36
+ CURRENT_SCHEMA_VERSION: () => CURRENT_SCHEMA_VERSION,
37
+ DEFAULT_LIMITS: () => DEFAULT_LIMITS,
38
+ DEFAULT_MIGRATIONS: () => DEFAULT_MIGRATIONS,
34
39
  FileTypeEnum: () => FileTypeEnum,
40
+ GLOBALLY_FORBIDDEN_PROPS: () => GLOBALLY_FORBIDDEN_PROPS,
35
41
  ITAccordion: () => ITAccordion,
36
42
  ITAlert: () => ITAlert,
37
43
  ITAvatar: () => ITAvatar,
@@ -75,6 +81,7 @@ __export(index_exports, {
75
81
  ITPopover: () => ITPopover,
76
82
  ITProgress: () => ITProgress,
77
83
  ITRadioGroup: () => ITRadioGroup,
84
+ ITSchemaRenderer: () => ITSchemaRenderer,
78
85
  ITSearchSelect: () => ITSearchSelect,
79
86
  ITSearchTable: () => ITSearchTable,
80
87
  ITSegmentedControl: () => ITSegmentedControl,
@@ -95,13 +102,39 @@ __export(index_exports, {
95
102
  ITToast: () => ITToast,
96
103
  ITTripleFilter: () => tripleFilter_default,
97
104
  ITWysiwyg: () => ITWysiwyg,
105
+ JsonEngineError: () => JsonEngineError,
106
+ NodeBoundary: () => NodeBoundary,
98
107
  UploadStatus: () => UploadStatus,
108
+ auditTree: () => auditTree,
109
+ axzyCatalog: () => axzyCatalog,
110
+ axzyCatalogTypes: () => axzyCatalogTypes,
111
+ buildVocabularyContract: () => buildVocabularyContract,
112
+ countPendingNodes: () => countPendingNodes,
113
+ createCatalog: () => createCatalog,
114
+ createLimitTracker: () => createLimitTracker,
99
115
  createValidationSchema: () => createValidationSchema,
100
116
  enMessages: () => en_default,
101
117
  esMessages: () => es_default,
118
+ formatPath: () => formatPath,
119
+ formatVocabularyForPrompt: () => formatVocabularyForPrompt,
120
+ getCatalogEntry: () => getCatalogEntry,
102
121
  getContrastTextColor: () => getContrastTextColor,
122
+ getExclusionReason: () => getExclusionReason,
123
+ hasPath: () => hasPath,
124
+ isExcludedType: () => isExcludedType,
103
125
  isLightColor: () => isLightColor,
126
+ isNodePending: () => isNodePending,
127
+ issue: () => issue,
128
+ migrateSchema: () => migrateSchema,
129
+ parsePartialSchema: () => parsePartialSchema,
130
+ parsePath: () => parsePath,
131
+ propPath: () => propPath,
132
+ pushPath: () => pushPath,
133
+ readPath: () => readPath,
134
+ renderNode: () => renderNode,
104
135
  resolveCssColor: () => resolveCssColor,
136
+ resolveLimits: () => resolveLimits,
137
+ resolveNode: () => resolveNode,
105
138
  useClickOutside: () => useClickOutside_default,
106
139
  useDebouncedSearch: () => useDebouncedSearch,
107
140
  useEditableRow: () => useEditableRow,
@@ -111,7 +144,8 @@ __export(index_exports, {
111
144
  useITThemeSafe: () => useITThemeSafe,
112
145
  useITTranslation: () => useITTranslation,
113
146
  useJsonRender: () => useJsonRender_default,
114
- useTableState: () => useTableState
147
+ useTableState: () => useTableState,
148
+ validateSchema: () => validateSchema
115
149
  });
116
150
  module.exports = __toCommonJS(index_exports);
117
151
 
@@ -1936,7 +1970,7 @@ function ITJsonRenderer({
1936
1970
  json,
1937
1971
  className
1938
1972
  }) {
1939
- const renderNode = (node) => {
1973
+ const renderNode2 = (node) => {
1940
1974
  if (node == null || typeof node === "boolean") {
1941
1975
  return null;
1942
1976
  }
@@ -1947,10 +1981,10 @@ function ITJsonRenderer({
1947
1981
  return node;
1948
1982
  }
1949
1983
  if (Array.isArray(node)) {
1950
- return node.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react13.default.Fragment, { children: renderNode(child) }, idx));
1984
+ return node.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react13.default.Fragment, { children: renderNode2(child) }, idx));
1951
1985
  }
1952
1986
  const { type, props = {}, children, text } = node;
1953
- const childContent = children !== void 0 ? renderNode(children) : text;
1987
+ const childContent = children !== void 0 ? renderNode2(children) : text;
1954
1988
  switch (type) {
1955
1989
  case "button":
1956
1990
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ITButton, { ...props, children: childContent });
@@ -1972,9 +2006,9 @@ function ITJsonRenderer({
1972
2006
  }
1973
2007
  };
1974
2008
  if (Array.isArray(json)) {
1975
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: (0, import_clsx7.default)(className), children: json.map((n, idx) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react13.default.Fragment, { children: renderNode(n) }, idx)) });
2009
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: (0, import_clsx7.default)(className), children: json.map((n, idx) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react13.default.Fragment, { children: renderNode2(n) }, idx)) });
1976
2010
  }
1977
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: (0, import_clsx7.default)(className), children: renderNode(json) });
2011
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: (0, import_clsx7.default)(className), children: renderNode2(json) });
1978
2012
  }
1979
2013
 
1980
2014
  // src/hooks/useJsonRender.tsx
@@ -6065,7 +6099,8 @@ function ITDialog({
6065
6099
  className,
6066
6100
  title,
6067
6101
  useFormHeader = false,
6068
- fullScreen = false
6102
+ fullScreen = false,
6103
+ padded = true
6069
6104
  }) {
6070
6105
  const { t } = useITTranslation();
6071
6106
  const modalRef = (0, import_react29.useRef)(null);
@@ -6094,7 +6129,7 @@ function ITDialog({
6094
6129
  "div",
6095
6130
  {
6096
6131
  ref: modalRef,
6097
- className: `overflow-hidden relative ${fullScreen ? "w-screen h-screen max-w-none rounded-none m-0 flex flex-col" : `${className || ""} ${useFormHeader ? "p-0" : "p-6"}`}`,
6132
+ className: `overflow-hidden relative ${fullScreen ? "w-screen h-screen max-w-none rounded-none m-0 flex flex-col" : `${className || ""} ${!padded || useFormHeader ? "p-0" : "p-6"}`}`,
6098
6133
  style: {
6099
6134
  backgroundColor: theme.card.backgroundColor,
6100
6135
  borderRadius: fullScreen ? "0" : theme.card.borderRadius,
@@ -6116,8 +6151,8 @@ function ITDialog({
6116
6151
  children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_fa15.FaRegTimesCircle, {})
6117
6152
  }
6118
6153
  ),
6119
- title && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }),
6120
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children })
6154
+ title && (padded ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ITText, { as: "h2", className: "text-xl font-semibold mb-4", children: title }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex items-center justify-between gap-3 px-6 py-4 border-b border-slate-200", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ITText, { as: "h2", className: "text-lg font-medium", children: title }) })),
6155
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: padded ? void 0 : "min-h-0 flex-1 flex flex-col", children })
6121
6156
  ] })
6122
6157
  }
6123
6158
  )
@@ -7044,7 +7079,8 @@ var ITImage = ({
7044
7079
  src,
7045
7080
  alt,
7046
7081
  className = "",
7047
- fallback = ""
7082
+ fallback = "",
7083
+ fit = "cover"
7048
7084
  }) => {
7049
7085
  const [imageError, setImageError] = (0, import_react36.useState)(false);
7050
7086
  const { t } = useITTranslation();
@@ -7060,7 +7096,8 @@ var ITImage = ({
7060
7096
  {
7061
7097
  src: fallback,
7062
7098
  alt: t("image.fallbackAlt"),
7063
- className: "w-full h-full object-cover"
7099
+ className: "w-full h-full",
7100
+ style: { objectFit: fit }
7064
7101
  }
7065
7102
  ) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
7066
7103
  "img",
@@ -7068,7 +7105,8 @@ var ITImage = ({
7068
7105
  src,
7069
7106
  alt,
7070
7107
  onError: handleImageError,
7071
- className: "w-full h-full object-cover"
7108
+ className: "w-full h-full",
7109
+ style: { objectFit: fit }
7072
7110
  }
7073
7111
  )
7074
7112
  }
@@ -11166,7 +11204,7 @@ function ITCodeTreeView({
11166
11204
  const line = analysis.nodeLines.get(pathKey(node.path))?.line;
11167
11205
  const isRoot = node.key === "";
11168
11206
  const isCollapsed = collapsed[node.key] ?? (node.childCount > 0 && node.level >= AUTO_EXPANDED_LEVELS);
11169
- const hasChildren = node.childCount > 0;
11207
+ const hasChildren2 = node.childCount > 0;
11170
11208
  const isPrimitive = node.kind !== "object" && node.kind !== "array";
11171
11209
  return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
11172
11210
  "div",
@@ -11174,7 +11212,7 @@ function ITCodeTreeView({
11174
11212
  className: "it-json-editor-tree-row",
11175
11213
  style: { paddingLeft: node.level * 14 },
11176
11214
  children: [
11177
- hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
11215
+ hasChildren2 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
11178
11216
  "button",
11179
11217
  {
11180
11218
  type: "button",
@@ -11189,7 +11227,7 @@ function ITCodeTreeView({
11189
11227
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "it-json-editor-tk-key", children: node.label }),
11190
11228
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "it-json-editor-tk-punct", children: ":" })
11191
11229
  ] }),
11192
- hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
11230
+ hasChildren2 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
11193
11231
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "[" : "{" }),
11194
11232
  isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "it-json-editor-tk-punct", children: node.kind === "array" ? "]" : "}" }),
11195
11233
  /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("span", { className: "it-json-editor-tree-badge", children: t("jsonEditor.childCount", { count: node.childCount }) })
@@ -12209,8 +12247,1452 @@ function EditorToggle({
12209
12247
  );
12210
12248
  }
12211
12249
 
12250
+ // src/json-renderer/kernel/SchemaRenderer.tsx
12251
+ var import_react53 = require("react");
12252
+
12253
+ // src/types/loader.types.ts
12254
+ var sizeClasses = {
12255
+ sm: "h-4 w-4",
12256
+ md: "h-8 w-8",
12257
+ lg: "h-12 w-12",
12258
+ xl: "h-16 w-16"
12259
+ };
12260
+
12261
+ // src/components/atoms/loader/loader.tsx
12262
+ var import_jsx_runtime74 = require("react/jsx-runtime");
12263
+ function ITLoader({
12264
+ size = "md",
12265
+ variant = "spinner",
12266
+ color = "primary",
12267
+ // Default to semantic primary
12268
+ className = ""
12269
+ }) {
12270
+ const { t } = useITTranslation();
12271
+ const isSemantic = color in theme.colors;
12272
+ const resolvedColor = isSemantic ? theme.colors[color][500] : color;
12273
+ const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
12274
+ const style = isCssValue ? { color: resolvedColor } : {};
12275
+ const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
12276
+ const colorClass = !isCssValue ? color : "";
12277
+ if (variant === "spinner") {
12278
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12279
+ "div",
12280
+ {
12281
+ className: `inline-block ${sizeClasses[size]} animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${colorClass} ${className}`,
12282
+ role: "status",
12283
+ style,
12284
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "span", className: "!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]", children: t("common.loading") })
12285
+ }
12286
+ );
12287
+ }
12288
+ if (variant === "dots") {
12289
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12290
+ "div",
12291
+ {
12292
+ className: `flex items-center justify-center space-x-2 ${className}`,
12293
+ children: [...Array(3)].map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12294
+ "div",
12295
+ {
12296
+ className: `${sizeClasses[size.replace(/l|g/, "")]} animate-bounce rounded-full ${colorClass}`,
12297
+ style: {
12298
+ ...bgStyle,
12299
+ animationDelay: `${i * 0.1}s`
12300
+ }
12301
+ },
12302
+ i
12303
+ ))
12304
+ }
12305
+ );
12306
+ }
12307
+ if (variant === "bar") {
12308
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12309
+ "div",
12310
+ {
12311
+ className: `w-full ${size === "sm" ? "h-1" : size === "md" ? "h-1.5" : size === "lg" ? "h-2" : "h-2.5"} bg-secondary-200 rounded-full overflow-hidden ${className}`,
12312
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12313
+ "div",
12314
+ {
12315
+ className: `h-full animate-progress ${colorClass}`,
12316
+ style: {
12317
+ backgroundColor: resolvedColor,
12318
+ // Simplified gradient for modern look, or keep it solid
12319
+ backgroundImage: isCssValue ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})` : void 0,
12320
+ animation: "progress 1.5s ease-in-out infinite"
12321
+ }
12322
+ }
12323
+ )
12324
+ }
12325
+ );
12326
+ }
12327
+ if (variant === "pulse") {
12328
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
12329
+ "div",
12330
+ {
12331
+ className: `rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`,
12332
+ style: bgStyle
12333
+ }
12334
+ );
12335
+ }
12336
+ return null;
12337
+ }
12338
+
12339
+ // src/json-renderer/catalog/catalog.props.ts
12340
+ var GLOBALLY_FORBIDDEN_PROPS = [
12341
+ "dangerouslySetInnerHTML",
12342
+ "render",
12343
+ "component",
12344
+ "children",
12345
+ // los hijos se declaran como nodos, nunca como prop
12346
+ "ref",
12347
+ "key",
12348
+ "style",
12349
+ // se permite solo si el catálogo lo declara explícitamente
12350
+ "icon",
12351
+ "actions",
12352
+ "action",
12353
+ "emptyAction",
12354
+ "fallback",
12355
+ "logo",
12356
+ "badge"
12357
+ ];
12358
+ function createCatalog(entries, excluded = {}) {
12359
+ const index = {};
12360
+ for (const entry of entries) {
12361
+ if (index[entry.type]) {
12362
+ throw new Error(`Cat\xE1logo duplicado: ${entry.type}`);
12363
+ }
12364
+ index[entry.type] = entry;
12365
+ }
12366
+ return { entries: index, excluded };
12367
+ }
12368
+ function getCatalogEntry(catalog, type) {
12369
+ return catalog.entries[type];
12370
+ }
12371
+ function isExcludedType(catalog, type) {
12372
+ return Boolean(catalog.excluded && type in catalog.excluded);
12373
+ }
12374
+ function getExclusionReason(catalog, type) {
12375
+ return catalog.excluded?.[type];
12376
+ }
12377
+
12378
+ // src/json-renderer/catalog/axzyCatalog.ts
12379
+ var COLORS = ["primary", "secondary", "success", "danger", "warning", "info", "purple", "error", "gray"];
12380
+ var SIZES = ["sm", "md", "lg"];
12381
+ var DIRECTIONS = ["row", "column"];
12382
+ var ALIGNS = ["start", "center", "end", "stretch", "baseline"];
12383
+ var JUSTIFIES = ["start", "center", "end", "between", "around", "evenly"];
12384
+ var WRAPS = ["nowrap", "wrap", "wrap-reverse"];
12385
+ var TEXT_PROPS = {
12386
+ className: { kind: "string", doc: "Clases extra del componente." }
12387
+ };
12388
+ var AXZY_CATALOG_ENTRIES = [
12389
+ {
12390
+ type: "ITText",
12391
+ component: ITText,
12392
+ children: true,
12393
+ text: true,
12394
+ summary: "Texto sem\xE1ntico. Usa `text` o `children` para el contenido.",
12395
+ props: {
12396
+ as: { kind: "enum", values: ["span", "p", "h1", "h2", "h3", "h4", "label", "div", "strong", "em"], default: "span", doc: "Etiqueta HTML sem\xE1ntica." },
12397
+ muted: { kind: "boolean", default: false, doc: "Aten\xFAa el color del texto." },
12398
+ ...TEXT_PROPS
12399
+ }
12400
+ },
12401
+ {
12402
+ type: "ITButton",
12403
+ component: ITButton,
12404
+ children: true,
12405
+ text: true,
12406
+ summary: "Bot\xF3n. `onClick` es una acci\xF3n registrada por el host.",
12407
+ props: {
12408
+ label: { kind: "string", doc: "Texto del bot\xF3n (alternativa a `text`)." },
12409
+ color: { kind: "enum", values: COLORS, default: "primary" },
12410
+ size: { kind: "enum", values: SIZES, default: "md" },
12411
+ variant: {
12412
+ kind: "enum",
12413
+ values: ["filled", "outlined", "raised", "rounded", "text", "raised-text", "icon-only", "link"],
12414
+ default: "filled"
12415
+ },
12416
+ disabled: { kind: "boolean", default: false },
12417
+ type: { kind: "enum", values: ["button", "submit", "reset"], default: "button" },
12418
+ ariaLabel: { kind: "string", doc: "Etiqueta accesible cuando el bot\xF3n no lleva texto." },
12419
+ title: { kind: "string" },
12420
+ onClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada." },
12421
+ ...TEXT_PROPS
12422
+ },
12423
+ forbidden: ["icon"]
12424
+ },
12425
+ {
12426
+ type: "ITCard",
12427
+ component: ITCard,
12428
+ children: true,
12429
+ summary: "Tarjeta con t\xEDtulo, imagen y contenido.",
12430
+ props: {
12431
+ title: { kind: "string" },
12432
+ image: { kind: "string", doc: "URL de la imagen de cabecera." },
12433
+ alt: { kind: "string" },
12434
+ onClick: { kind: "action" },
12435
+ imageClassName: { kind: "string" },
12436
+ titleClassName: { kind: "string" },
12437
+ contentClassName: { kind: "string" },
12438
+ actionClassName: { kind: "string" },
12439
+ ...TEXT_PROPS
12440
+ },
12441
+ forbidden: ["actions"]
12442
+ },
12443
+ {
12444
+ type: "ITAlert",
12445
+ component: ITAlert,
12446
+ children: true,
12447
+ text: true,
12448
+ summary: "Aviso con variante sem\xE1ntica.",
12449
+ props: {
12450
+ variant: { kind: "enum", values: ["info", "success", "warning", "error"], default: "info" },
12451
+ title: { kind: "string" },
12452
+ dismissible: { kind: "boolean", default: false },
12453
+ onDismiss: { kind: "action" },
12454
+ ...TEXT_PROPS
12455
+ },
12456
+ forbidden: ["icon"]
12457
+ },
12458
+ {
12459
+ type: "ITEmptyState",
12460
+ component: ITEmptyState,
12461
+ text: true,
12462
+ summary: "Estado vac\xEDo con t\xEDtulo, descripci\xF3n y acci\xF3n.",
12463
+ props: {
12464
+ title: { kind: "string", required: true },
12465
+ description: { kind: "string" },
12466
+ ...TEXT_PROPS
12467
+ },
12468
+ forbidden: ["icon", "action"]
12469
+ },
12470
+ {
12471
+ type: "ITStatCard",
12472
+ component: ITStatCard,
12473
+ summary: "M\xE9trica con valor y tendencia.",
12474
+ props: {
12475
+ label: { kind: "string", required: true },
12476
+ value: { kind: "string", required: true, doc: "Valor ya formateado o n\xFAmero." },
12477
+ trend: { kind: "string" },
12478
+ trendDirection: { kind: "enum", values: ["up", "down", "neutral"] },
12479
+ color: { kind: "string", doc: "Color CSS del icono." },
12480
+ onClick: { kind: "action" },
12481
+ ...TEXT_PROPS
12482
+ },
12483
+ forbidden: ["icon"]
12484
+ },
12485
+ {
12486
+ type: "ITChip",
12487
+ component: ITChip,
12488
+ children: true,
12489
+ text: true,
12490
+ summary: "Etiqueta compacta, opcionalmente removible o seleccionable.",
12491
+ props: {
12492
+ label: { kind: "string" },
12493
+ color: { kind: "enum", values: COLORS, default: "gray" },
12494
+ size: { kind: "enum", values: SIZES, default: "md" },
12495
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12496
+ removable: { kind: "boolean", default: false },
12497
+ selected: { kind: "boolean", default: false },
12498
+ disabled: { kind: "boolean", default: false },
12499
+ onRemove: { kind: "action" },
12500
+ onClick: { kind: "action" },
12501
+ ...TEXT_PROPS
12502
+ },
12503
+ forbidden: ["icon"]
12504
+ },
12505
+ {
12506
+ type: "ITBadget",
12507
+ component: ITBadget,
12508
+ children: true,
12509
+ text: true,
12510
+ summary: "Insignia de estado.",
12511
+ props: {
12512
+ label: { kind: "string" },
12513
+ color: { kind: "enum", values: COLORS, default: "primary" },
12514
+ size: { kind: "enum", values: SIZES, default: "md" },
12515
+ variant: { kind: "enum", values: ["soft", "filled", "outlined"], default: "soft" },
12516
+ ...TEXT_PROPS
12517
+ }
12518
+ },
12519
+ {
12520
+ type: "ITAvatar",
12521
+ component: ITAvatar,
12522
+ summary: "Avatar con imagen o iniciales.",
12523
+ props: {
12524
+ src: { kind: "string" },
12525
+ alt: { kind: "string" },
12526
+ initials: { kind: "string", doc: "Se usa cuando no hay imagen." },
12527
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"] },
12528
+ color: { kind: "string" },
12529
+ onClick: { kind: "action" },
12530
+ ...TEXT_PROPS
12531
+ },
12532
+ forbidden: ["badge"]
12533
+ },
12534
+ {
12535
+ type: "ITDivider",
12536
+ component: ITDivider,
12537
+ summary: "Separador horizontal o vertical.",
12538
+ props: {
12539
+ orientation: { kind: "enum", values: ["horizontal", "vertical"], default: "horizontal" },
12540
+ color: { kind: "string" },
12541
+ thickness: { kind: "string" },
12542
+ ...TEXT_PROPS
12543
+ }
12544
+ },
12545
+ {
12546
+ type: "ITStack",
12547
+ component: ITStack,
12548
+ children: true,
12549
+ summary: "Pila con direcci\xF3n y separaci\xF3n uniforme.",
12550
+ props: {
12551
+ direction: { kind: "enum", values: DIRECTIONS, default: "column" },
12552
+ spacing: { kind: "number", default: 0 },
12553
+ alignItems: { kind: "enum", values: ALIGNS },
12554
+ justifyContent: { kind: "enum", values: JUSTIFIES },
12555
+ flexWrap: { kind: "enum", values: WRAPS },
12556
+ ...TEXT_PROPS
12557
+ },
12558
+ forbidden: ["divider", "style"]
12559
+ },
12560
+ {
12561
+ type: "ITFlex",
12562
+ component: ITFlex,
12563
+ children: true,
12564
+ summary: "Contenedor flex completo.",
12565
+ props: {
12566
+ direction: { kind: "enum", values: DIRECTIONS, default: "row" },
12567
+ align: { kind: "enum", values: ALIGNS },
12568
+ justify: { kind: "enum", values: JUSTIFIES },
12569
+ wrap: { kind: "enum", values: WRAPS },
12570
+ gap: { kind: "number", default: 0 },
12571
+ grow: { kind: "boolean" },
12572
+ shrink: { kind: "boolean" },
12573
+ basis: { kind: "string" },
12574
+ ...TEXT_PROPS
12575
+ },
12576
+ forbidden: ["style", "onClick"]
12577
+ },
12578
+ {
12579
+ type: "ITGrid",
12580
+ component: ITGrid,
12581
+ children: true,
12582
+ summary: "Rejilla de 12 columnas; `item` para una celda.",
12583
+ props: {
12584
+ container: { kind: "boolean", default: false },
12585
+ item: { kind: "boolean", default: false },
12586
+ spacing: { kind: "number", default: 0 },
12587
+ columns: { kind: "integer", default: 12, doc: "Columnas del contenedor." },
12588
+ xs: { kind: "integer" },
12589
+ sm: { kind: "integer" },
12590
+ md: { kind: "integer" },
12591
+ lg: { kind: "integer" },
12592
+ xl: { kind: "integer" },
12593
+ ...TEXT_PROPS
12594
+ },
12595
+ forbidden: ["style"]
12596
+ },
12597
+ {
12598
+ type: "ITLoader",
12599
+ component: ITLoader,
12600
+ summary: "Indicador de carga.",
12601
+ props: {
12602
+ variant: { kind: "enum", values: ["spinner", "dots", "bar", "pulse"], default: "spinner" },
12603
+ size: { kind: "enum", values: ["xs", "sm", "md", "lg", "xl"], default: "md" },
12604
+ color: { kind: "string" },
12605
+ ...TEXT_PROPS
12606
+ }
12607
+ },
12608
+ {
12609
+ type: "ITSkeleton",
12610
+ component: ITSkeleton,
12611
+ summary: "Marcador de carga con forma.",
12612
+ props: {
12613
+ variant: { kind: "enum", values: ["text", "rect", "circle"], default: "text" },
12614
+ width: { kind: "string" },
12615
+ height: { kind: "string" },
12616
+ count: { kind: "integer", default: 1 },
12617
+ ...TEXT_PROPS
12618
+ },
12619
+ forbidden: ["style"]
12620
+ },
12621
+ {
12622
+ type: "ITProgress",
12623
+ component: ITProgress,
12624
+ summary: "Barra de progreso.",
12625
+ props: {
12626
+ value: { kind: "number", default: 0 },
12627
+ max: { kind: "number", default: 100 },
12628
+ variant: { kind: "enum", values: ["determinate", "indeterminate"], default: "determinate" },
12629
+ color: { kind: "enum", values: COLORS, default: "primary" },
12630
+ size: { kind: "enum", values: SIZES, default: "md" },
12631
+ ...TEXT_PROPS
12632
+ },
12633
+ forbidden: ["style"]
12634
+ },
12635
+ {
12636
+ type: "ITDataTable",
12637
+ component: ITDataTable,
12638
+ summary: "Tabla con paginaci\xF3n, orden y filtros. Los datos llegan de una fuente que el host resuelve (`$source`).",
12639
+ props: {
12640
+ columns: {
12641
+ kind: "columns",
12642
+ required: true,
12643
+ doc: "Columnas: { key, label, type, sortable, filter, currencyMX }."
12644
+ },
12645
+ fetchData: {
12646
+ kind: "data",
12647
+ required: true,
12648
+ doc: 'Referencia a una fuente: { "$source": "usuarios" }. El host la convierte en un fetcher.'
12649
+ },
12650
+ title: { kind: "string", doc: "T\xEDtulo opcional sobre la tabla." },
12651
+ defaultItemsPerPage: { kind: "integer", default: 5, doc: "Filas por p\xE1gina al abrir." },
12652
+ itemsPerPageOptions: { kind: "array", doc: "Opciones del paginador, p. ej. [5, 10, 20]." },
12653
+ debounceMs: { kind: "integer", default: 400, doc: "Espera antes de refiltrar al teclear." },
12654
+ variant: { kind: "enum", values: ["default", "striped", "bordered", "minimal"], default: "default" },
12655
+ size: { kind: "enum", values: SIZES, default: "md" },
12656
+ density: { kind: "enum", values: ["compact", "normal", "comfortable"], default: "normal" },
12657
+ layout: { kind: "enum", values: ["auto", "fixed"], default: "auto" },
12658
+ showVerticalBorder: { kind: "boolean", default: true },
12659
+ autoCardBreakpoint: { kind: "integer", default: 0, doc: "Ancho (px) por debajo del cual cae a tarjetas." },
12660
+ onRowClick: { kind: "action", doc: "Nombre de una acci\xF3n registrada; recibe la fila." },
12661
+ className: { kind: "string" },
12662
+ containerClassName: { kind: "string" }
12663
+ },
12664
+ forbidden: ["renderCard", "loadingIndicator"]
12665
+ },
12666
+ {
12667
+ type: "ITImage",
12668
+ component: image_default,
12669
+ summary: "Imagen con respaldo si falla la carga.",
12670
+ props: {
12671
+ src: { kind: "string", required: true },
12672
+ alt: { kind: "string" },
12673
+ fallback: { kind: "string", doc: "URL de respaldo." },
12674
+ onClick: { kind: "action" },
12675
+ ...TEXT_PROPS
12676
+ }
12677
+ }
12678
+ ];
12679
+ var AXZY_EXCLUDED_TYPES = {
12680
+ ITJsonRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12681
+ ITSchemaRenderer: "Recursi\xF3n: un esquema no puede pedir otro renderer.",
12682
+ ITJSONEditor: "Ejecuta entrada del usuario como c\xF3digo.",
12683
+ ITFormBuilder: "Se sustituye por el nodo `form` del motor.",
12684
+ ITWysiwyg: "Produce HTML, que se salta la lista blanca.",
12685
+ ITI18nProvider: "Lo monta el host, no el esquema.",
12686
+ ITThemeProvider: "Lo monta el host, no el esquema.",
12687
+ ITLayout: "El shell lo declara el router, no un nodo suelto.",
12688
+ ITNavbar: "El shell lo declara el router, no un nodo suelto.",
12689
+ ITSidebar: "El shell lo declara el router, no un nodo suelto.",
12690
+ ITTopBar: "El shell lo declara el router, no un nodo suelto."
12691
+ };
12692
+ var axzyCatalog = createCatalog(AXZY_CATALOG_ENTRIES, AXZY_EXCLUDED_TYPES);
12693
+ var axzyCatalogTypes = Object.keys(axzyCatalog.entries);
12694
+
12695
+ // src/json-renderer/shared/limits.ts
12696
+ var DEFAULT_LIMITS = {
12697
+ maxNodes: 5e3,
12698
+ maxDepth: 40,
12699
+ maxMsPerChunk: 8,
12700
+ actionTimeoutMs: 15e3,
12701
+ maxEffectChain: 5
12702
+ };
12703
+ function resolveLimits(overrides = {}) {
12704
+ const merged = { ...DEFAULT_LIMITS, ...overrides };
12705
+ for (const [key, value] of Object.entries(merged)) {
12706
+ if (!Number.isFinite(value) || value < 0) {
12707
+ throw new RangeError(`L\xEDmite inv\xE1lido: ${key} = ${String(value)}`);
12708
+ }
12709
+ }
12710
+ return merged;
12711
+ }
12712
+ function createLimitTracker(limits = DEFAULT_LIMITS) {
12713
+ let nodes = 0;
12714
+ let deepest = 0;
12715
+ let exceeded = false;
12716
+ return {
12717
+ visit(depth) {
12718
+ if (depth > deepest) deepest = depth;
12719
+ if (nodes >= limits.maxNodes || depth > limits.maxDepth) {
12720
+ exceeded = true;
12721
+ return false;
12722
+ }
12723
+ nodes += 1;
12724
+ return true;
12725
+ },
12726
+ get nodes() {
12727
+ return nodes;
12728
+ },
12729
+ get deepest() {
12730
+ return deepest;
12731
+ },
12732
+ get exceeded() {
12733
+ return exceeded;
12734
+ }
12735
+ };
12736
+ }
12737
+
12738
+ // src/json-renderer/kernel/NodeBoundary.tsx
12739
+ var import_react51 = __toESM(require("react"), 1);
12740
+
12741
+ // src/json-renderer/shared/errors.ts
12742
+ var JsonEngineError = class extends Error {
12743
+ constructor(code, message, path, hint) {
12744
+ super(`${code} ${path ? `en ${path}: ` : ""}${message}`);
12745
+ /** Código estable del catálogo de avisos. */
12746
+ __publicField(this, "code");
12747
+ /** Ruta del esquema donde se produjo. */
12748
+ __publicField(this, "path");
12749
+ /** Sugerencia accionable. */
12750
+ __publicField(this, "hint");
12751
+ this.name = "JsonEngineError";
12752
+ this.code = code;
12753
+ this.path = path;
12754
+ this.hint = hint;
12755
+ }
12756
+ /** Convierte el error en el aviso que consume la interfaz y el informe. */
12757
+ toIssue(severity = "error") {
12758
+ return {
12759
+ code: this.code,
12760
+ severity,
12761
+ message: this.message.replace(/^JR\d{3}\s?(en .*?: )?/, ""),
12762
+ path: this.path,
12763
+ hint: this.hint
12764
+ };
12765
+ }
12766
+ };
12767
+ function issue(code, message, path = "", options = {}) {
12768
+ return {
12769
+ code,
12770
+ severity: options.severity ?? "error",
12771
+ message,
12772
+ path,
12773
+ hint: options.hint
12774
+ };
12775
+ }
12776
+
12777
+ // src/json-renderer/kernel/NodeBoundary.tsx
12778
+ var NodeBoundary = class extends import_react51.default.Component {
12779
+ constructor() {
12780
+ super(...arguments);
12781
+ __publicField(this, "state", { failed: false });
12782
+ }
12783
+ static getDerivedStateFromError() {
12784
+ return { failed: true };
12785
+ }
12786
+ componentDidCatch(error) {
12787
+ this.props.onError?.(error, this.props.path);
12788
+ }
12789
+ render() {
12790
+ if (this.state.failed) return this.props.fallback ?? null;
12791
+ return this.props.children;
12792
+ }
12793
+ };
12794
+
12795
+ // src/json-renderer/stream/tolerantParse.ts
12796
+ function isPending(value) {
12797
+ return typeof value === "object" && value !== null && value.$pending === true;
12798
+ }
12799
+ var TRUNCATED_CONTAINERS = /* @__PURE__ */ new WeakSet();
12800
+ function finalize(value, counter) {
12801
+ if (Array.isArray(value)) {
12802
+ return value.map((item) => finalize(item, counter)).filter((item) => item !== void 0);
12803
+ }
12804
+ if (value && typeof value === "object") {
12805
+ if (isPending(value)) {
12806
+ counter.pending += 1;
12807
+ return void 0;
12808
+ }
12809
+ const out = { ...value };
12810
+ let hasPendingChild = false;
12811
+ for (const [key, nested] of Object.entries(out)) {
12812
+ const resolved = finalize(nested, counter);
12813
+ if (resolved === void 0 && isPending(nested)) {
12814
+ hasPendingChild = true;
12815
+ delete out[key];
12816
+ } else {
12817
+ out[key] = resolved;
12818
+ }
12819
+ }
12820
+ const truncated = TRUNCATED_CONTAINERS.has(value);
12821
+ if ((hasPendingChild || truncated) && "type" in out) {
12822
+ out.$status = "pending";
12823
+ }
12824
+ return out;
12825
+ }
12826
+ return value;
12827
+ }
12828
+ var WHITESPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\r"]);
12829
+ var TolerantParser = class {
12830
+ constructor(text) {
12831
+ __publicField(this, "text", text);
12832
+ __publicField(this, "index", 0);
12833
+ /** `true` cuando se detuvo porque el texto se acabó (y no por un error). */
12834
+ __publicField(this, "truncated", false);
12835
+ /** `true` cuando encontró algo que no puede interpretar. */
12836
+ __publicField(this, "broken", false);
12837
+ }
12838
+ /** Offset actual. */
12839
+ get offset() {
12840
+ return this.index;
12841
+ }
12842
+ /** `true` si el consumo se detuvo por falta de texto. */
12843
+ get isTruncated() {
12844
+ return this.truncated;
12845
+ }
12846
+ /** Salta el espacio en blanco. */
12847
+ skip() {
12848
+ while (this.index < this.text.length && WHITESPACE.has(this.text[this.index])) this.index += 1;
12849
+ }
12850
+ /** Carácter actual, o `undefined` si se acabó. */
12851
+ peek() {
12852
+ return this.text[this.index];
12853
+ }
12854
+ /** Intenta consumir un literal (`true`, `false`, `null`). */
12855
+ tryLiteral(literal) {
12856
+ if (!this.text.startsWith(literal, this.index)) return void 0;
12857
+ const end = this.index + literal.length;
12858
+ if (end > this.text.length) {
12859
+ this.index = this.text.length;
12860
+ this.truncated = true;
12861
+ return { $pending: true };
12862
+ }
12863
+ if (this.text.slice(this.index, end) !== literal) {
12864
+ const prefix = this.text.slice(this.index);
12865
+ if (literal.startsWith(prefix)) {
12866
+ this.index = this.text.length;
12867
+ this.truncated = true;
12868
+ return { $pending: true };
12869
+ }
12870
+ return void 0;
12871
+ }
12872
+ this.index = end;
12873
+ if (literal === "true") return true;
12874
+ if (literal === "false") return false;
12875
+ return null;
12876
+ }
12877
+ /** Lee una cadena. Marca pendiente si no encuentra la comilla de cierre. */
12878
+ readString() {
12879
+ this.index += 1;
12880
+ let out = "";
12881
+ while (this.index < this.text.length) {
12882
+ const char = this.text[this.index];
12883
+ if (char === "\\") {
12884
+ const next = this.text[this.index + 1];
12885
+ if (next === void 0) {
12886
+ this.index = this.text.length;
12887
+ this.truncated = true;
12888
+ return { $pending: true };
12889
+ }
12890
+ out += unescapeChar(next);
12891
+ this.index += 2;
12892
+ continue;
12893
+ }
12894
+ if (char === '"') {
12895
+ this.index += 1;
12896
+ return out;
12897
+ }
12898
+ out += char;
12899
+ this.index += 1;
12900
+ }
12901
+ this.truncated = true;
12902
+ return { $pending: true };
12903
+ }
12904
+ /** Lee un número. Devuelve el texto crudo como número, o pendiente. */
12905
+ readNumber() {
12906
+ const start = this.index;
12907
+ if (this.peek() === "-") this.index += 1;
12908
+ while (this.index < this.text.length && /[0-9.eE+-]/.test(this.text[this.index])) this.index += 1;
12909
+ const raw = this.text.slice(start, this.index);
12910
+ if (raw === "" || raw === "-") {
12911
+ this.index = this.text.length;
12912
+ this.truncated = true;
12913
+ return { $pending: true };
12914
+ }
12915
+ const value = Number(raw);
12916
+ if (Number.isNaN(value)) {
12917
+ this.broken = true;
12918
+ return { $pending: true };
12919
+ }
12920
+ return value;
12921
+ }
12922
+ /** Marca un contenedor como truncado (se cerró por falta de texto). */
12923
+ markTruncated(container) {
12924
+ this.truncated = true;
12925
+ TRUNCATED_CONTAINERS.add(container);
12926
+ }
12927
+ /** Lee un array. */
12928
+ readArray() {
12929
+ this.index += 1;
12930
+ const items = [];
12931
+ this.skip();
12932
+ if (this.peek() === "]") {
12933
+ this.index += 1;
12934
+ return items;
12935
+ }
12936
+ for (; ; ) {
12937
+ this.skip();
12938
+ if (this.peek() === void 0) {
12939
+ if (items.length === 0) {
12940
+ this.truncated = true;
12941
+ return { $pending: true };
12942
+ }
12943
+ this.markTruncated(items);
12944
+ return items;
12945
+ }
12946
+ const value = this.readValue();
12947
+ if (isPending(value)) {
12948
+ if (items.length === 0) {
12949
+ this.truncated = true;
12950
+ return { $pending: true };
12951
+ }
12952
+ this.markTruncated(items);
12953
+ return items;
12954
+ }
12955
+ items.push(value);
12956
+ this.skip();
12957
+ const char = this.peek();
12958
+ if (char === ",") {
12959
+ this.index += 1;
12960
+ continue;
12961
+ }
12962
+ if (char === "]") {
12963
+ this.index += 1;
12964
+ return items;
12965
+ }
12966
+ if (char === void 0) {
12967
+ this.markTruncated(items);
12968
+ return items;
12969
+ }
12970
+ this.broken = true;
12971
+ return items;
12972
+ }
12973
+ }
12974
+ /** Lee un objeto. */
12975
+ readObject() {
12976
+ this.index += 1;
12977
+ const out = {};
12978
+ this.skip();
12979
+ if (this.peek() === "}") {
12980
+ this.index += 1;
12981
+ return out;
12982
+ }
12983
+ for (; ; ) {
12984
+ this.skip();
12985
+ const char = this.peek();
12986
+ if (char === void 0) {
12987
+ if (!Object.keys(out).length) {
12988
+ this.truncated = true;
12989
+ return { $pending: true };
12990
+ }
12991
+ this.markTruncated(out);
12992
+ return out;
12993
+ }
12994
+ if (char !== '"') {
12995
+ this.broken = true;
12996
+ if (!Object.keys(out).length) return { $pending: true };
12997
+ this.markTruncated(out);
12998
+ return out;
12999
+ }
13000
+ const key = this.readString();
13001
+ if (isPending(key)) {
13002
+ if (!Object.keys(out).length) {
13003
+ this.truncated = true;
13004
+ return { $pending: true };
13005
+ }
13006
+ this.markTruncated(out);
13007
+ return out;
13008
+ }
13009
+ this.skip();
13010
+ if (this.peek() !== ":") {
13011
+ this.broken = this.peek() !== void 0;
13012
+ if (!Object.keys(out).length) {
13013
+ this.truncated = true;
13014
+ return { $pending: true };
13015
+ }
13016
+ this.markTruncated(out);
13017
+ return out;
13018
+ }
13019
+ this.index += 1;
13020
+ this.skip();
13021
+ const value = this.readValue();
13022
+ if (isPending(value)) {
13023
+ if (!Object.keys(out).length) {
13024
+ this.truncated = true;
13025
+ return { $pending: true };
13026
+ }
13027
+ this.markTruncated(out);
13028
+ return out;
13029
+ }
13030
+ out[key] = value;
13031
+ this.skip();
13032
+ const separator = this.peek();
13033
+ if (separator === ",") {
13034
+ this.index += 1;
13035
+ continue;
13036
+ }
13037
+ if (separator === "}") {
13038
+ this.index += 1;
13039
+ return out;
13040
+ }
13041
+ if (separator === void 0) {
13042
+ this.markTruncated(out);
13043
+ return out;
13044
+ }
13045
+ this.broken = true;
13046
+ return out;
13047
+ }
13048
+ }
13049
+ /** Lee cualquier valor. */
13050
+ readValue() {
13051
+ this.skip();
13052
+ const char = this.peek();
13053
+ if (char === void 0) {
13054
+ this.truncated = true;
13055
+ return { $pending: true };
13056
+ }
13057
+ if (char === "{") return this.readObject();
13058
+ if (char === "[") return this.readArray();
13059
+ if (char === '"') {
13060
+ const value = this.readString();
13061
+ return isPending(value) ? { $pending: true } : value;
13062
+ }
13063
+ if (char === "t" || char === "f" || char === "n") {
13064
+ const literal = char === "t" ? this.tryLiteral("true") : char === "f" ? this.tryLiteral("false") : this.tryLiteral("null");
13065
+ return literal === void 0 ? { $pending: true } : literal;
13066
+ }
13067
+ if (char === "-" || /[0-9]/.test(char)) return this.readNumber();
13068
+ this.broken = true;
13069
+ this.index = this.text.length;
13070
+ return { $pending: true };
13071
+ }
13072
+ /** Parsea el documento completo (o hasta donde llegue). */
13073
+ parse() {
13074
+ this.skip();
13075
+ if (this.peek() === void 0) {
13076
+ return { value: void 0, truncated: true, broken: false };
13077
+ }
13078
+ const value = this.readValue();
13079
+ this.skip();
13080
+ const truncated = this.truncated || this.index < this.text.length;
13081
+ return { value, truncated, broken: this.broken };
13082
+ }
13083
+ };
13084
+ function unescapeChar(char) {
13085
+ switch (char) {
13086
+ case "n":
13087
+ return "\n";
13088
+ case "t":
13089
+ return " ";
13090
+ case "r":
13091
+ return "\r";
13092
+ case "b":
13093
+ return "\b";
13094
+ case "f":
13095
+ return "\f";
13096
+ default:
13097
+ return char;
13098
+ }
13099
+ }
13100
+ function parsePartialSchema(text) {
13101
+ const parser = new TolerantParser(text);
13102
+ const { value, truncated, broken } = parser.parse();
13103
+ if (value === void 0) {
13104
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: 0 };
13105
+ }
13106
+ const counter = { pending: 0 };
13107
+ const finalized = finalize(value, counter);
13108
+ if (finalized === void 0 || finalized === null) {
13109
+ return { tree: null, status: "pending", offset: parser.offset, broken, pendingNodes: counter.pending };
13110
+ }
13111
+ const tree = finalized;
13112
+ return {
13113
+ tree,
13114
+ status: truncated || counter.pending > 0 ? "pending" : "complete",
13115
+ offset: parser.offset,
13116
+ broken,
13117
+ pendingNodes: counter.pending
13118
+ };
13119
+ }
13120
+ function isNodePending(node) {
13121
+ return node?.$status === "pending";
13122
+ }
13123
+
13124
+ // src/json-renderer/kernel/renderNode.tsx
13125
+ var import_react52 = __toESM(require("react"), 1);
13126
+
13127
+ // src/json-renderer/shared/paths.ts
13128
+ function pushPath(path, segment) {
13129
+ return [...path, segment];
13130
+ }
13131
+ function formatPath(path) {
13132
+ let out = "";
13133
+ for (const segment of path) {
13134
+ if (typeof segment === "number") out += `[${segment}]`;
13135
+ else out += out ? `.${segment}` : segment;
13136
+ }
13137
+ return out;
13138
+ }
13139
+ function parsePath(rendered) {
13140
+ if (!rendered) return [];
13141
+ return rendered.split(/\.(?![^[]*])/).flatMap((part) => {
13142
+ const match = part.match(/^([^[\]]*)((?:\[\d+\])*)$/);
13143
+ if (!match) return [part];
13144
+ const [, key, indexes] = match;
13145
+ const segments = key ? [key] : [];
13146
+ for (const index of indexes.match(/\d+/g) ?? []) segments.push(Number(index));
13147
+ return segments;
13148
+ });
13149
+ }
13150
+ function readPath(source, path) {
13151
+ let cursor = source;
13152
+ for (const segment of path) {
13153
+ if (cursor === null || typeof cursor !== "object") return void 0;
13154
+ cursor = cursor[segment];
13155
+ }
13156
+ return cursor;
13157
+ }
13158
+ function hasPath(source, path) {
13159
+ if (path.length === 0) return true;
13160
+ const parent = readPath(source, path.slice(0, -1));
13161
+ if (parent === null || typeof parent !== "object") return false;
13162
+ return Object.prototype.hasOwnProperty.call(parent, path[path.length - 1]);
13163
+ }
13164
+ function propPath(nodePath, prop) {
13165
+ return pushPath(pushPath(nodePath, "props"), prop);
13166
+ }
13167
+
13168
+ // src/json-renderer/catalog/resolve.ts
13169
+ function isSchemaReference(value) {
13170
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
13171
+ const keys = Object.keys(value);
13172
+ if (keys.length === 0) return false;
13173
+ return keys.some((key) => key === "i18n" || key.startsWith("$"));
13174
+ }
13175
+ function coerce(value, spec) {
13176
+ switch (spec.kind) {
13177
+ case "string":
13178
+ if (typeof value === "string") return value;
13179
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
13180
+ return void 0;
13181
+ case "number":
13182
+ case "integer": {
13183
+ if (typeof value === "number" && Number.isFinite(value)) {
13184
+ return spec.kind === "integer" ? Math.trunc(value) : value;
13185
+ }
13186
+ if (typeof value === "string" && value.trim() !== "" && Number.isFinite(Number(value))) {
13187
+ const parsed = Number(value);
13188
+ return spec.kind === "integer" ? Math.trunc(parsed) : parsed;
13189
+ }
13190
+ return void 0;
13191
+ }
13192
+ case "boolean":
13193
+ if (typeof value === "boolean") return value;
13194
+ if (value === "true") return true;
13195
+ if (value === "false") return false;
13196
+ return void 0;
13197
+ case "enum":
13198
+ if (typeof value !== "string") return void 0;
13199
+ return spec.values?.includes(value) ? value : void 0;
13200
+ case "array":
13201
+ return Array.isArray(value) ? value : void 0;
13202
+ case "object":
13203
+ return value && typeof value === "object" ? value : void 0;
13204
+ default:
13205
+ return value;
13206
+ }
13207
+ }
13208
+ function resolveNode(node, catalog, path) {
13209
+ const issues = [];
13210
+ const type = node.type;
13211
+ if (typeof type !== "string" || type === "") {
13212
+ issues.push(issue("JR021", "El nodo no declara `type`.", formatPath(path), { severity: "error" }));
13213
+ return { ok: false, issues };
13214
+ }
13215
+ if (isExcludedType(catalog, type)) {
13216
+ const reason = getExclusionReason(catalog, type);
13217
+ issues.push(
13218
+ issue("JR010", `El tipo \`${type}\` est\xE1 excluido del cat\xE1logo.`, formatPath(path), {
13219
+ severity: "error",
13220
+ hint: reason
13221
+ })
13222
+ );
13223
+ return { ok: false, issues };
13224
+ }
13225
+ const entry = catalog.entries[type];
13226
+ if (!entry) {
13227
+ const known = Object.keys(catalog.entries).slice(0, 8).join(", ");
13228
+ issues.push(
13229
+ issue("JR010", `El tipo \`${type}\` no est\xE1 en el cat\xE1logo.`, formatPath(path), {
13230
+ severity: "error",
13231
+ hint: `Tipos disponibles (primeros 8): ${known}\u2026`
13232
+ })
13233
+ );
13234
+ return { ok: false, issues };
13235
+ }
13236
+ const specs = entry.props ?? {};
13237
+ const props = {};
13238
+ const actions = {};
13239
+ const input = node.props ?? {};
13240
+ for (const [name, spec] of Object.entries(specs)) {
13241
+ if (spec.default !== void 0) props[name] = spec.default;
13242
+ }
13243
+ for (const [name, raw] of Object.entries(input)) {
13244
+ const forbiddenByEntry = entry.forbidden?.includes(name);
13245
+ const forbiddenGlobally = GLOBALLY_FORBIDDEN_PROPS.includes(name);
13246
+ if (forbiddenByEntry || forbiddenGlobally) {
13247
+ issues.push(
13248
+ issue("JR011", `La prop \`${name}\` est\xE1 prohibida en \`${type}\`.`, formatPath(propPath(path, name)), {
13249
+ severity: "warning",
13250
+ hint: "Los nodos React se declaran como hijos del esquema, no como props."
13251
+ })
13252
+ );
13253
+ continue;
13254
+ }
13255
+ const spec = specs[name];
13256
+ if (!spec) {
13257
+ issues.push(
13258
+ issue("JR011", `La prop \`${name}\` no est\xE1 declarada para \`${type}\`.`, formatPath(propPath(path, name)), {
13259
+ severity: "warning",
13260
+ hint: "Se ignora. Si es necesaria, a\xF1\xE1dela al cat\xE1logo con su tipo."
13261
+ })
13262
+ );
13263
+ continue;
13264
+ }
13265
+ if (spec.kind === "action") {
13266
+ actions[name] = raw;
13267
+ continue;
13268
+ }
13269
+ if (isSchemaReference(raw)) {
13270
+ props[name] = raw;
13271
+ continue;
13272
+ }
13273
+ const value = coerce(raw, spec);
13274
+ if (value === void 0) {
13275
+ issues.push(
13276
+ issue(
13277
+ "JR011",
13278
+ `Valor inv\xE1lido para \`${name}\` en \`${type}\`.`,
13279
+ formatPath(propPath(path, name)),
13280
+ { severity: "warning", hint: spec.values ? `Admitidos: ${spec.values.join(", ")}` : `Se esperaba ${spec.kind}.` }
13281
+ )
13282
+ );
13283
+ continue;
13284
+ }
13285
+ props[name] = value;
13286
+ }
13287
+ for (const [name, spec] of Object.entries(specs)) {
13288
+ if (spec.required && props[name] === void 0) {
13289
+ issues.push(
13290
+ issue("JR011", `Falta la prop obligatoria \`${name}\` en \`${type}\`.`, formatPath(propPath(path, name)), {
13291
+ severity: "error"
13292
+ })
13293
+ );
13294
+ }
13295
+ }
13296
+ if (node.children !== void 0 && !entry.children) {
13297
+ issues.push(
13298
+ issue("JR011", `\`${type}\` no acepta \`children\`.`, formatPath([...path, "children"]), {
13299
+ severity: "warning",
13300
+ hint: "Los hijos se ignoran."
13301
+ })
13302
+ );
13303
+ }
13304
+ return { ok: true, entry, props, actions, issues };
13305
+ }
13306
+
13307
+ // src/json-renderer/kernel/renderNode.tsx
13308
+ function childList(node) {
13309
+ if (!node || node.children === void 0 || node.children === null) return [];
13310
+ return Array.isArray(node.children) ? node.children : [node.children];
13311
+ }
13312
+ function renderNode(node, options) {
13313
+ const { catalog, path, issues, renderChildren } = options;
13314
+ if (!node || typeof node !== "object") {
13315
+ return null;
13316
+ }
13317
+ if (isNodePending(node)) {
13318
+ return options.pendingFallback ?? null;
13319
+ }
13320
+ const resolved = resolveNode(node, catalog, path);
13321
+ issues.push(...resolved.issues);
13322
+ if (!resolved.ok) {
13323
+ return null;
13324
+ }
13325
+ const { entry, props, actions } = resolved;
13326
+ const finalProps = {};
13327
+ for (const [name, value] of Object.entries(props)) {
13328
+ finalProps[name] = options.resolveValue ? options.resolveValue(value, path) : value;
13329
+ }
13330
+ for (const [name, action] of Object.entries(actions)) {
13331
+ const handler = options.resolveAction?.(node, name, action, path);
13332
+ if (typeof handler === "function") finalProps[name] = handler;
13333
+ }
13334
+ const content = renderChildren ? renderChildren(node, path) : null;
13335
+ const rawText = entry.text && node.text !== void 0 ? node.text : void 0;
13336
+ const text = rawText === void 0 ? void 0 : options.resolveValue ? options.resolveValue(rawText, path) : rawText;
13337
+ const children = content ?? text;
13338
+ const element = import_react52.default.createElement(
13339
+ entry.component,
13340
+ { ...finalProps, key: node.id ?? path.join("-"), id: node.id },
13341
+ children
13342
+ );
13343
+ return options.wrap ? options.wrap(node, path, element) : element;
13344
+ }
13345
+
13346
+ // src/json-renderer/kernel/partial.ts
13347
+ function auditTree(schema, limits) {
13348
+ const tracker = createLimitTracker(limits);
13349
+ const issues = [];
13350
+ let pending = 0;
13351
+ let depth = 0;
13352
+ const walk = (node, path, level) => {
13353
+ if (!node || typeof node !== "object") return;
13354
+ if (!tracker.visit(level)) return;
13355
+ if (level > depth) depth = level;
13356
+ if (isNodePending(node)) pending += 1;
13357
+ const children = childList(node);
13358
+ children.forEach((child, index) => {
13359
+ walk(child, `${path}[${index}]`, level + 1);
13360
+ });
13361
+ if (node.fallback) walk(node.fallback, `${path}.fallback`, level + 1);
13362
+ };
13363
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13364
+ content.forEach((node, index) => walk(node, `content[${index}]`, 0));
13365
+ if (tracker.exceeded) {
13366
+ issues.push(
13367
+ issue(
13368
+ "JR013",
13369
+ `El esquema supera el presupuesto (${tracker.nodes} nodos, profundidad ${tracker.deepest}).`,
13370
+ "content",
13371
+ {
13372
+ severity: "warning",
13373
+ hint: `M\xE1ximo configurado: ${limits.maxNodes} nodos y profundidad ${limits.maxDepth}. La parte que sobra no se pinta.`
13374
+ }
13375
+ )
13376
+ );
13377
+ }
13378
+ return { nodes: tracker.nodes, depth: tracker.deepest, pending, exceeded: tracker.exceeded, issues };
13379
+ }
13380
+ function countPendingNodes(schema) {
13381
+ if (!schema) return 0;
13382
+ let total = 0;
13383
+ const walk = (node) => {
13384
+ if (!node || typeof node !== "object") return;
13385
+ if (isNodePending(node)) total += 1;
13386
+ for (const child of childList(node)) walk(child);
13387
+ };
13388
+ const content = Array.isArray(schema.content) ? schema.content : [schema.content];
13389
+ for (const node of content) walk(node);
13390
+ return total;
13391
+ }
13392
+
13393
+ // src/json-renderer/kernel/SchemaRenderer.tsx
13394
+ var import_jsx_runtime75 = require("react/jsx-runtime");
13395
+ function renderTree(node, path, context, level) {
13396
+ if (!node || typeof node !== "object") return null;
13397
+ if (level > context.limits.maxDepth) return null;
13398
+ const issues = context.issues;
13399
+ if (node.id) context.nodeIds.add(node.id);
13400
+ const reportIssue = (issue2) => {
13401
+ issues.push(issue2);
13402
+ context.onIssue?.(issue2);
13403
+ };
13404
+ const issuesBefore = issues.length;
13405
+ const element = renderNode(node, {
13406
+ catalog: context.catalog,
13407
+ path,
13408
+ issues,
13409
+ resolveValue: context.resolveValue,
13410
+ resolveAction: context.resolveAction,
13411
+ pendingFallback: context.pendingFallback,
13412
+ renderChildren: (current, currentPath) => {
13413
+ const children = childList(current);
13414
+ if (children.length === 0) return void 0;
13415
+ return children.map(
13416
+ (child, index) => renderTree(child, [...currentPath, "children", index], context, level + 1)
13417
+ );
13418
+ }
13419
+ });
13420
+ for (let index = issuesBefore; index < issues.length; index += 1) {
13421
+ context.onIssue?.(issues[index]);
13422
+ }
13423
+ const fallback = node.fallback ? renderTree(node.fallback, [...path, "fallback"], context, level + 1) : context.pendingFallback ?? null;
13424
+ const wrapped = /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
13425
+ NodeBoundary,
13426
+ {
13427
+ path: path.join("."),
13428
+ fallback,
13429
+ onError: (error, errorPath) => reportIssue({
13430
+ code: "JR012",
13431
+ severity: "error",
13432
+ message: error.message,
13433
+ path: errorPath,
13434
+ hint: "El nodo se ha aislado; el resto de la pantalla sigue pint\xE1ndose."
13435
+ }),
13436
+ children: element
13437
+ },
13438
+ String(path.join("-"))
13439
+ );
13440
+ return wrapped;
13441
+ }
13442
+ function ITSchemaRenderer({
13443
+ schema,
13444
+ catalog = axzyCatalog,
13445
+ limits,
13446
+ resolveValue,
13447
+ resolveAction,
13448
+ pendingFallback,
13449
+ onIssue,
13450
+ className
13451
+ }) {
13452
+ const resolvedLimits = (0, import_react53.useMemo)(() => resolveLimits(limits), [limits]);
13453
+ const issues = [];
13454
+ const nodeIds = /* @__PURE__ */ new Set();
13455
+ const audit = (0, import_react53.useMemo)(
13456
+ () => schema ? auditTree(schema, resolvedLimits) : null,
13457
+ [schema, resolvedLimits]
13458
+ );
13459
+ const context = (0, import_react53.useMemo)(
13460
+ () => ({
13461
+ catalog,
13462
+ nodeIds,
13463
+ limits: resolvedLimits,
13464
+ issues,
13465
+ onIssue,
13466
+ resolveValue,
13467
+ resolveAction,
13468
+ pendingFallback
13469
+ }),
13470
+ // `issues` es un array nuevo en cada render a propósito: acumular avisos
13471
+ // entre renders duplicaría los avisos de esquemas que no han cambiado.
13472
+ // eslint-disable-next-line react-hooks/exhaustive-deps
13473
+ [catalog, resolvedLimits, onIssue, resolveValue, resolveAction, pendingFallback]
13474
+ );
13475
+ const content = schema ? (Array.isArray(schema.content) ? schema.content : [schema.content]).filter(
13476
+ (node) => Boolean(node) && typeof node === "object"
13477
+ ) : [];
13478
+ const children = content.slice(0, resolvedLimits.maxNodes).map((node, index) => renderTree(node, ["content", index], context, 0)).filter(Boolean);
13479
+ const collected = [...audit?.issues ?? [], ...issues];
13480
+ const signature = collected.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13481
+ const reported = (0, import_react53.useRef)("");
13482
+ (0, import_react53.useEffect)(() => {
13483
+ const all = [...collected];
13484
+ for (const id of nodeIds) {
13485
+ if (!document.getElementById(id)) {
13486
+ all.push({
13487
+ code: "JR014",
13488
+ severity: "warning",
13489
+ message: `El \`id\` "${id}" no lleg\xF3 al DOM.`,
13490
+ path: id,
13491
+ hint: "El componente no reenv\xEDa props al elemento. Pon el id en un nodo que s\xED lo haga (por ejemplo ITText) o en un contenedor del host."
13492
+ });
13493
+ }
13494
+ }
13495
+ const firma = all.map((issue2) => `${issue2.code}:${issue2.path}`).join("|");
13496
+ if (!onIssue || reported.current === firma) return;
13497
+ reported.current = firma;
13498
+ for (const issue2 of all) onIssue(issue2);
13499
+ }, [signature, onIssue]);
13500
+ if (!schema || children.length === 0) return null;
13501
+ return className ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className, children }) : /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_jsx_runtime75.Fragment, { children });
13502
+ }
13503
+
13504
+ // src/json-renderer/validation/validate.ts
13505
+ var CURRENT_SCHEMA_VERSION = 1;
13506
+ function validateNodes(node, path, catalog, errors, warnings) {
13507
+ if (!node || typeof node !== "object") {
13508
+ errors.push(issue("JR021", "El nodo no es un objeto.", formatPath(path), { severity: "error" }));
13509
+ return 0;
13510
+ }
13511
+ if (isNodePending(node)) return 1;
13512
+ const resolved = resolveNode(node, catalog, path);
13513
+ for (const item of resolved.issues) {
13514
+ (item.severity === "error" ? errors : warnings).push(item);
13515
+ }
13516
+ let pending = 0;
13517
+ const children = node.children === void 0 ? [] : Array.isArray(node.children) ? node.children : [node.children];
13518
+ children.forEach((child, index) => {
13519
+ pending += validateNodes(child, [...path, "children", index], catalog, errors, warnings);
13520
+ });
13521
+ return pending;
13522
+ }
13523
+ function validateSchema(schema, options = {}) {
13524
+ const catalog = options.catalog ?? axzyCatalog;
13525
+ const maxVersion = options.maxVersion ?? CURRENT_SCHEMA_VERSION;
13526
+ const errors = [];
13527
+ const warnings = [];
13528
+ if (schema === null || schema === void 0) {
13529
+ return { verdict: "invalid", errors: [issue("JR020", "No hay esquema que validar.", "")], warnings, pendingNodes: 0 };
13530
+ }
13531
+ if (typeof schema !== "object" || Array.isArray(schema)) {
13532
+ return {
13533
+ verdict: "invalid",
13534
+ errors: [issue("JR020", "El esquema debe ser un objeto.", "", { severity: "error" })],
13535
+ warnings,
13536
+ pendingNodes: 0
13537
+ };
13538
+ }
13539
+ const candidate = schema;
13540
+ if (candidate.$schema !== void 0 && candidate.$schema !== "axzy/screen") {
13541
+ errors.push(
13542
+ issue("JR020", `El formato declarado no es \`axzy/screen\`.`, "$schema", {
13543
+ severity: "error",
13544
+ hint: 'Usa `$schema: "axzy/screen"` o quita la propiedad.'
13545
+ })
13546
+ );
13547
+ }
13548
+ if (candidate.version === void 0) {
13549
+ errors.push(issue("JR020", "Falta `version` en el esquema.", "version", { severity: "error" }));
13550
+ } else if (typeof candidate.version !== "number" || !Number.isInteger(candidate.version)) {
13551
+ errors.push(issue("JR020", "`version` debe ser un entero.", "version", { severity: "error" }));
13552
+ } else if (candidate.version > maxVersion) {
13553
+ errors.push(
13554
+ issue("JR020", `La versi\xF3n ${candidate.version} es m\xE1s nueva que la soportada (${maxVersion}).`, "version", {
13555
+ severity: "error",
13556
+ hint: "Actualiza el motor o migra el esquema."
13557
+ })
13558
+ );
13559
+ }
13560
+ if (typeof candidate.id !== "string" || candidate.id.trim() === "") {
13561
+ errors.push(issue("JR020", "Falta `id` en el esquema.", "id", { severity: "error" }));
13562
+ }
13563
+ if (candidate.content === void 0) {
13564
+ errors.push(issue("JR020", "El esquema no declara `content`.", "content", { severity: "error" }));
13565
+ return { verdict: "invalid", errors, warnings, pendingNodes: 0, version: candidate.version };
13566
+ }
13567
+ const content = Array.isArray(candidate.content) ? candidate.content : [candidate.content];
13568
+ if (content.length === 0) {
13569
+ warnings.push(
13570
+ issue("JR021", "`content` est\xE1 vac\xEDo: la pantalla se pinta sin nodos.", "content", { severity: "warning" })
13571
+ );
13572
+ }
13573
+ let pendingNodes = 0;
13574
+ content.map((node, index) => ({ node, index })).filter(({ node }) => node !== void 0 && node !== null).forEach(({ node, index }) => {
13575
+ pendingNodes += validateNodes(node, ["content", index], catalog, errors, warnings);
13576
+ });
13577
+ const verdict = errors.length > 0 ? "invalid" : pendingNodes > 0 ? "partial" : "valid";
13578
+ return { verdict, errors, warnings, pendingNodes, version: candidate.version };
13579
+ }
13580
+
13581
+ // src/json-renderer/validation/migrate.ts
13582
+ var DEFAULT_MIGRATIONS = {};
13583
+ function migrateSchema(schema, targetVersion, migrations = DEFAULT_MIGRATIONS) {
13584
+ const from = typeof schema.version === "number" ? schema.version : 0;
13585
+ const issues = [];
13586
+ if (from === targetVersion) {
13587
+ return { schema, migrated: false, from, to: targetVersion, issues };
13588
+ }
13589
+ if (from > targetVersion) {
13590
+ issues.push(
13591
+ issue("JR020", `El esquema es de una versi\xF3n posterior (${from}) a la del motor (${targetVersion}).`, "version", {
13592
+ severity: "error",
13593
+ hint: "Actualiza el motor; no se puede degradar un esquema."
13594
+ })
13595
+ );
13596
+ return { schema, migrated: false, from, to: targetVersion, issues };
13597
+ }
13598
+ let current = schema;
13599
+ let version = from;
13600
+ while (version < targetVersion) {
13601
+ const migration = migrations[version];
13602
+ if (!migration) {
13603
+ issues.push(
13604
+ issue("JR070", `No hay migraci\xF3n registrada de la versi\xF3n ${version} a la ${version + 1}.`, "version", {
13605
+ severity: "error",
13606
+ hint: "Registra la migraci\xF3n en `migrations` o guarda el esquema en la versi\xF3n actual."
13607
+ })
13608
+ );
13609
+ return { schema: current, migrated: false, from, to: version, issues };
13610
+ }
13611
+ current = { ...migration(current), version: version + 1 };
13612
+ version += 1;
13613
+ }
13614
+ return { schema: current, migrated: version !== from, from, to: version, issues };
13615
+ }
13616
+
13617
+ // src/json-renderer/vocabulary/buildContract.ts
13618
+ var RULES = [
13619
+ 'Emite SOLO JSON v\xE1lido con la forma: { $schema: "axzy/screen", version, id, content }.',
13620
+ "`content` es un nodo o un array de nodos; cada nodo necesita `type` del cat\xE1logo.",
13621
+ "Usa solo props declaradas para ese `type`; el resto se ignora y se avisa.",
13622
+ "Los hijos se expresan con `children` (nodos) y los textos con `text`, nunca con props de nodo React.",
13623
+ 'Las acciones se declaran por nombre: `"onClick": { "action": "nombre.registrado" }`. No hay c\xF3digo en el JSON.',
13624
+ "Prohibido: HTML crudo, URLs, fetch, expresiones JS y props como icon/actions/render.",
13625
+ 'Los textos visibles deben ser claves de i18n: { "i18n": "namespace.clave" }.'
13626
+ ];
13627
+ function buildMinimal(entry) {
13628
+ const props = {};
13629
+ for (const [name, spec] of Object.entries(entry.props ?? {})) {
13630
+ if (!spec.required) continue;
13631
+ props[name] = sampleValue(name, spec);
13632
+ }
13633
+ const node = { type: entry.type };
13634
+ if (Object.keys(props).length > 0) node.props = props;
13635
+ if (entry.text) node.text = "Texto";
13636
+ return node;
13637
+ }
13638
+ function sampleValue(name, spec) {
13639
+ if (spec.values?.length) return spec.values[0];
13640
+ if (spec.kind === "number" || spec.kind === "integer") return 1;
13641
+ if (spec.kind === "boolean") return false;
13642
+ if (spec.kind === "i18n") return { i18n: `ejemplo.${name}` };
13643
+ return name === "src" ? "/imagen.png" : `${name}`;
13644
+ }
13645
+ function buildVocabularyContract(catalog = axzyCatalog, schemaVersion = CURRENT_SCHEMA_VERSION) {
13646
+ const components2 = Object.values(catalog.entries).map((entry) => ({
13647
+ type: entry.type,
13648
+ summary: entry.summary,
13649
+ children: Boolean(entry.children),
13650
+ text: Boolean(entry.text),
13651
+ props: Object.entries(entry.props ?? {}).map(([name, spec]) => ({
13652
+ name,
13653
+ kind: spec.kind,
13654
+ required: Boolean(spec.required),
13655
+ values: spec.values ? [...spec.values] : void 0,
13656
+ default: spec.default,
13657
+ doc: spec.doc
13658
+ })),
13659
+ forbidden: [...entry.forbidden ?? []],
13660
+ minimal: buildMinimal(entry)
13661
+ })).sort((a, b) => a.type.localeCompare(b.type));
13662
+ return {
13663
+ $schema: "axzy/vocabulary",
13664
+ schemaVersion,
13665
+ rules: RULES,
13666
+ components: components2,
13667
+ excluded: catalog.excluded ?? {}
13668
+ };
13669
+ }
13670
+ function formatVocabularyForPrompt(contract) {
13671
+ const lines = [
13672
+ `# Contrato de vocabulario AXZY (formato v${contract.schemaVersion})`,
13673
+ "",
13674
+ "Reglas:",
13675
+ ...contract.rules.map((rule) => `- ${rule}`),
13676
+ "",
13677
+ "Componentes:"
13678
+ ];
13679
+ for (const component of contract.components) {
13680
+ const props = component.props.map((prop) => {
13681
+ const parts = [`${prop.name}:${prop.kind}${prop.required ? "*" : ""}`];
13682
+ if (prop.values?.length) parts.push(`(${prop.values.join("|")})`);
13683
+ return parts.join(" ");
13684
+ }).join(", ");
13685
+ lines.push(`- ${component.type}${component.summary ? ` \u2014 ${component.summary}` : ""}`);
13686
+ if (props) lines.push(` props: ${props}`);
13687
+ if (component.children) lines.push(" children: s\xED");
13688
+ if (component.text) lines.push(" text: s\xED");
13689
+ lines.push(` m\xEDnimo: ${JSON.stringify(component.minimal)}`);
13690
+ }
13691
+ return lines.join("\n");
13692
+ }
13693
+
12212
13694
  // src/components/organisms/dropfile/dropfile.tsx
12213
- var import_react51 = require("react");
13695
+ var import_react54 = require("react");
12214
13696
  var import_react_dropzone = require("react-dropzone");
12215
13697
  var import_clsx54 = __toESM(require("clsx"), 1);
12216
13698
 
@@ -12240,7 +13722,7 @@ var UploadStatus = /* @__PURE__ */ ((UploadStatus2) => {
12240
13722
  })(UploadStatus || {});
12241
13723
 
12242
13724
  // src/components/organisms/dropfile/dropfile.tsx
12243
- var import_jsx_runtime74 = require("react/jsx-runtime");
13725
+ var import_jsx_runtime76 = require("react/jsx-runtime");
12244
13726
  var ITDropfile = ({
12245
13727
  onFileSelect,
12246
13728
  onCancel,
@@ -12257,15 +13739,15 @@ var ITDropfile = ({
12257
13739
  modalTitle
12258
13740
  }) => {
12259
13741
  const { t } = useITTranslation();
12260
- const [isModalOpen, setIsModalOpen] = (0, import_react51.useState)(false);
12261
- const [selectedFile, setSelectedFile] = (0, import_react51.useState)(null);
12262
- const [fileType, setFileType] = (0, import_react51.useState)(null);
12263
- const [imagePreview, setImagePreview] = (0, import_react51.useState)(initialPreviewUrl || null);
12264
- const [isConfirmed, setIsConfirmed] = (0, import_react51.useState)(false);
12265
- const [internalUploadStatus, setInternalUploadStatus] = (0, import_react51.useState)(
13742
+ const [isModalOpen, setIsModalOpen] = (0, import_react54.useState)(false);
13743
+ const [selectedFile, setSelectedFile] = (0, import_react54.useState)(null);
13744
+ const [fileType, setFileType] = (0, import_react54.useState)(null);
13745
+ const [imagePreview, setImagePreview] = (0, import_react54.useState)(initialPreviewUrl || null);
13746
+ const [isConfirmed, setIsConfirmed] = (0, import_react54.useState)(false);
13747
+ const [internalUploadStatus, setInternalUploadStatus] = (0, import_react54.useState)(
12266
13748
  initialPreviewUrl ? "subido" /* UPLOADED */ : "pendiente" /* PENDING */
12267
13749
  );
12268
- (0, import_react51.useEffect)(() => {
13750
+ (0, import_react54.useEffect)(() => {
12269
13751
  if (initialPreviewUrl && !selectedFile) {
12270
13752
  setImagePreview(initialPreviewUrl);
12271
13753
  if (externalStatus === void 0) setInternalUploadStatus("subido" /* UPLOADED */);
@@ -12380,9 +13862,9 @@ var ITDropfile = ({
12380
13862
  }
12381
13863
  };
12382
13864
  const { label, color, dotColor } = config2[status];
12383
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `inline-flex items-center gap-2 px-2.5 py-1 rounded-full border ${color}`, children: [
12384
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: `w-2 h-2 rounded-full ${dotColor}` }),
12385
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "span", className: "text-xs font-medium flex items-center gap-1.5", children: label })
13865
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `inline-flex items-center gap-2 px-2.5 py-1 rounded-full border ${color}`, children: [
13866
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: `w-2 h-2 rounded-full ${dotColor}` }),
13867
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { as: "span", className: "text-xs font-medium flex items-center gap-1.5", children: label })
12386
13868
  ] });
12387
13869
  };
12388
13870
  const onDrop = (acceptedFiles) => {
@@ -12414,12 +13896,12 @@ var ITDropfile = ({
12414
13896
  accept: getAcceptedFileTypes(),
12415
13897
  maxFiles: 1
12416
13898
  });
12417
- (0, import_react51.useEffect)(() => {
13899
+ (0, import_react54.useEffect)(() => {
12418
13900
  const renderPDF = async () => {
12419
13901
  };
12420
13902
  renderPDF();
12421
13903
  }, [selectedFile, fileType]);
12422
- (0, import_react51.useEffect)(() => {
13904
+ (0, import_react54.useEffect)(() => {
12423
13905
  return () => {
12424
13906
  if (imagePreview) {
12425
13907
  URL.revokeObjectURL(imagePreview);
@@ -12456,7 +13938,7 @@ var ITDropfile = ({
12456
13938
  const handleDelete = () => {
12457
13939
  handleCancel();
12458
13940
  };
12459
- (0, import_react51.useEffect)(() => {
13941
+ (0, import_react54.useEffect)(() => {
12460
13942
  if (view === "button" && isConfirmed && uploadStatus === "subido" /* UPLOADED */) {
12461
13943
  const timeout = setTimeout(() => {
12462
13944
  setIsModalOpen(false);
@@ -12473,21 +13955,21 @@ var ITDropfile = ({
12473
13955
  return () => clearTimeout(timeout);
12474
13956
  }
12475
13957
  }, [view, isConfirmed, uploadStatus, externalStatus, onStatusChange]);
12476
- const headerRow = /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
12477
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("label", { className: "block text-sm font-semibold text-secondary-700", children: [
12478
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(ITText, { as: "span", children: [
13958
+ const headerRow = /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
13959
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("label", { className: "block text-sm font-semibold text-secondary-700", children: [
13960
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(ITText, { as: "span", children: [
12479
13961
  t("dropfile.upload"),
12480
13962
  " "
12481
13963
  ] }),
12482
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(ITText, { as: "span", className: "text-secondary-400 font-normal text-xs", children: [
13964
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(ITText, { as: "span", className: "text-secondary-400 font-normal text-xs", children: [
12483
13965
  "(",
12484
13966
  getFileExtensions(),
12485
13967
  ")"
12486
13968
  ] })
12487
13969
  ] }),
12488
- showStatusBadge && selectedFile && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(StatusBadge, { status: uploadStatus })
13970
+ showStatusBadge && selectedFile && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(StatusBadge, { status: uploadStatus })
12489
13971
  ] });
12490
- const dropZoneOrPreview = /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(import_jsx_runtime74.Fragment, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
13972
+ const dropZoneOrPreview = /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_jsx_runtime76.Fragment, { children: !selectedFile && !imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
12491
13973
  "div",
12492
13974
  {
12493
13975
  ...getRootProps(),
@@ -12497,41 +13979,41 @@ var ITDropfile = ({
12497
13979
  ${isDragActive ? "border-primary-500 bg-primary-50 scale-[1.01]" : "border-secondary-300 bg-white hover:border-primary-400 hover:bg-secondary-50"}
12498
13980
  `,
12499
13981
  children: [
12500
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("input", { ...getInputProps() }),
12501
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: `mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? "bg-primary-100" : "bg-secondary-100 group-hover:bg-primary-50"}`, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
13982
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("input", { ...getInputProps() }),
13983
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: `mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? "bg-primary-100" : "bg-secondary-100 group-hover:bg-primary-50"}`, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12502
13984
  "svg",
12503
13985
  {
12504
13986
  className: `w-6 h-6 transition-colors duration-300 ${isDragActive ? "text-primary-600" : "text-secondary-400 group-hover:text-primary-500"}`,
12505
13987
  fill: "none",
12506
13988
  viewBox: "0 0 24 24",
12507
13989
  stroke: "currentColor",
12508
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" })
13990
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" })
12509
13991
  }
12510
13992
  ) }),
12511
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "text-center space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "p", className: `text-sm font-medium transition-colors duration-300 ${isDragActive ? "text-primary-700" : "text-secondary-700"}`, children: isDragActive ? t("dropfile.dropHere") : t("dropfile.clickOrDrag") }) })
13993
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "text-center space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { as: "p", className: `text-sm font-medium transition-colors duration-300 ${isDragActive ? "text-primary-700" : "text-secondary-700"}`, children: isDragActive ? t("dropfile.dropHere") : t("dropfile.clickOrDrag") }) })
12512
13994
  ]
12513
13995
  }
12514
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "w-full bg-white border border-secondary-200 rounded-xl shadow-sm overflow-hidden animate-fade-in", children: [
12515
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "flex items-center justify-between p-3 bg-secondary-50 border-b border-secondary-100", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
12516
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "flex-shrink-0 w-8 h-8 rounded-lg bg-primary-100 flex items-center justify-center text-primary-600", children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }),
12517
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "min-w-0", children: [
12518
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "p", className: "text-xs font-medium text-secondary-900 truncate", title: selectedFile?.name || t("dropfile.imageLoaded"), children: selectedFile?.name || t("dropfile.imageLoaded") }),
12519
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "p", className: "text-[10px] text-secondary-500", children: selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : "" })
13996
+ ) : /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "w-full bg-white border border-secondary-200 rounded-xl shadow-sm overflow-hidden animate-fade-in", children: [
13997
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "flex items-center justify-between p-3 bg-secondary-50 border-b border-secondary-100", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
13998
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "flex-shrink-0 w-8 h-8 rounded-lg bg-primary-100 flex items-center justify-center text-primary-600", children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }),
13999
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "min-w-0", children: [
14000
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { as: "p", className: "text-xs font-medium text-secondary-900 truncate", title: selectedFile?.name || t("dropfile.imageLoaded"), children: selectedFile?.name || t("dropfile.imageLoaded") }),
14001
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { as: "p", className: "text-[10px] text-secondary-500", children: selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : "" })
12520
14002
  ] })
12521
14003
  ] }) }),
12522
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: (0, import_clsx54.default)("relative bg-secondary-100 flex items-center justify-center", !contentClassName ? "max-h-[200px] min-h-[100px] overflow-auto" : contentClassName), children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
14004
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: (0, import_clsx54.default)("relative bg-secondary-100 flex items-center justify-center", !contentClassName ? "max-h-[200px] min-h-[100px] overflow-auto" : contentClassName), children: selectedFile && fileType?.startsWith("image/") || !selectedFile && imagePreview ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12523
14005
  "img",
12524
14006
  {
12525
14007
  src: imagePreview,
12526
14008
  alt: t("dropfile.previewAlt"),
12527
14009
  className: "w-full h-full object-contain max-h-[200px]"
12528
14010
  }
12529
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "py-8 flex flex-col items-center text-secondary-400", children: [
12530
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-10 h-10 mb-2 opacity-50", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
12531
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { as: "span", className: "text-xs", children: t("dropfile.noPreview") })
14011
+ ) : /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "py-8 flex flex-col items-center text-secondary-400", children: [
14012
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-10 h-10 mb-2 opacity-50", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
14013
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { as: "span", className: "text-xs", children: t("dropfile.noPreview") })
12532
14014
  ] }) }),
12533
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
12534
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
14015
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2", children: !isConfirmed ? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
14016
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12535
14017
  ITButton,
12536
14018
  {
12537
14019
  type: "button",
@@ -12539,10 +14021,10 @@ var ITDropfile = ({
12539
14021
  color: "secondary",
12540
14022
  size: "sm",
12541
14023
  onClick: handleCancel,
12542
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { children: t("common.cancel") })
14024
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { children: t("common.cancel") })
12543
14025
  }
12544
14026
  ),
12545
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
14027
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12546
14028
  ITButton,
12547
14029
  {
12548
14030
  type: "button",
@@ -12550,13 +14032,13 @@ var ITDropfile = ({
12550
14032
  color: "primary",
12551
14033
  size: "sm",
12552
14034
  onClick: handleConfirm,
12553
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex items-center gap-2", children: [
12554
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { children: t("common.confirm") }),
12555
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
14035
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center gap-2", children: [
14036
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { children: t("common.confirm") }),
14037
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })
12556
14038
  ] })
12557
14039
  }
12558
14040
  )
12559
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
14041
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
12560
14042
  ITButton,
12561
14043
  {
12562
14044
  type: "button",
@@ -12565,12 +14047,12 @@ var ITDropfile = ({
12565
14047
  size: "sm",
12566
14048
  onClick: handleDelete,
12567
14049
  children: [
12568
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
12569
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { children: t("common.delete") })
14050
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
14051
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { children: t("common.delete") })
12570
14052
  ]
12571
14053
  }
12572
14054
  ) }),
12573
- uploadStatus === "subiendo" /* UPLOADING */ && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "px-4 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full bg-secondary-200 rounded-full h-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
14055
+ uploadStatus === "subiendo" /* UPLOADING */ && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "px-4 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "w-full bg-secondary-200 rounded-full h-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12574
14056
  "div",
12575
14057
  {
12576
14058
  className: "bg-primary-600 h-1.5 rounded-full transition-all duration-1000 ease-out",
@@ -12583,8 +14065,8 @@ var ITDropfile = ({
12583
14065
  ] }) });
12584
14066
  if (view === "button") {
12585
14067
  const hasFile = Boolean(selectedFile || imagePreview);
12586
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: (0, import_clsx54.default)("inline-block", containerClassName), children: [
12587
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
14068
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: (0, import_clsx54.default)("inline-block", containerClassName), children: [
14069
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
12588
14070
  ITButton,
12589
14071
  {
12590
14072
  type: "button",
@@ -12592,20 +14074,20 @@ var ITDropfile = ({
12592
14074
  color: hasFile ? "primary" : "secondary",
12593
14075
  size: "sm",
12594
14076
  onClick: () => setIsModalOpen(true),
12595
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex items-center gap-2 max-w-[220px]", children: [
12596
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-4 h-4 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
12597
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITText, { className: "truncate", children: selectedFile?.name || (hasFile ? t("dropfile.fileLoaded") : buttonLabel ?? t("dropfile.upload")) }),
12598
- showStatusBadge && hasFile && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(StatusBadge, { status: uploadStatus })
14077
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center gap-2 max-w-[220px]", children: [
14078
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "w-4 h-4 flex-shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
14079
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITText, { className: "truncate", children: selectedFile?.name || (hasFile ? t("dropfile.fileLoaded") : buttonLabel ?? t("dropfile.upload")) }),
14080
+ showStatusBadge && hasFile && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(StatusBadge, { status: uploadStatus })
12599
14081
  ] })
12600
14082
  }
12601
14083
  ),
12602
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ITDialog, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: modalTitle ?? buttonLabel ?? t("dropfile.upload"), children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "w-full transition-all duration-300", children: [
14084
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(ITDialog, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: modalTitle ?? buttonLabel ?? t("dropfile.upload"), children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "w-full transition-all duration-300", children: [
12603
14085
  headerRow,
12604
14086
  dropZoneOrPreview
12605
14087
  ] }) })
12606
14088
  ] });
12607
14089
  }
12608
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: (0, import_clsx54.default)("w-full transition-all duration-300", containerClassName), children: [
14090
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: (0, import_clsx54.default)("w-full transition-all duration-300", containerClassName), children: [
12609
14091
  headerRow,
12610
14092
  dropZoneOrPreview
12611
14093
  ] });
@@ -12613,13 +14095,13 @@ var ITDropfile = ({
12613
14095
  var dropfile_default = ITDropfile;
12614
14096
 
12615
14097
  // src/components/templates/layout/layout.tsx
12616
- var import_react53 = require("react");
14098
+ var import_react56 = require("react");
12617
14099
  var import_clsx55 = __toESM(require("clsx"), 1);
12618
14100
 
12619
14101
  // src/components/organisms/topbar/topbar.tsx
12620
14102
  var import_fa32 = require("react-icons/fa");
12621
- var import_react52 = require("react");
12622
- var import_jsx_runtime75 = require("react/jsx-runtime");
14103
+ var import_react55 = require("react");
14104
+ var import_jsx_runtime77 = require("react/jsx-runtime");
12623
14105
  function ITTopBar({
12624
14106
  logo,
12625
14107
  logoText,
@@ -12636,10 +14118,10 @@ function ITTopBar({
12636
14118
  const flat = useITFlatAppearance();
12637
14119
  const { t } = useITTranslation();
12638
14120
  const initials = (userMenu?.userName ?? "").trim().split(/\s+/).slice(0, 2).map((word) => word.charAt(0).toUpperCase()).join("");
12639
- const [isUserMenuOpen, setIsUserMenuOpen] = (0, import_react52.useState)(false);
12640
- const userMenuRef = (0, import_react52.useRef)(null);
14121
+ const [isUserMenuOpen, setIsUserMenuOpen] = (0, import_react55.useState)(false);
14122
+ const userMenuRef = (0, import_react55.useRef)(null);
12641
14123
  useClickOutside_default(userMenuRef, () => setIsUserMenuOpen(false));
12642
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14124
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12643
14125
  "header",
12644
14126
  {
12645
14127
  className: `sticky top-0 z-40 transition-all duration-300 ${flat ? "" : "backdrop-blur-md"}`,
@@ -12648,9 +14130,9 @@ function ITTopBar({
12648
14130
  borderBottom: "1px solid var(--it-topbar-border, rgba(15, 23, 42, 0.06))",
12649
14131
  boxShadow: flat ? "none" : "var(--shadow-xs)"
12650
14132
  },
12651
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: `flex items-center justify-between px-6 lg:px-8 ${flat ? "h-[64px]" : "h-[72px]"}`, children: [
12652
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-center gap-5", children: [
12653
- showMobileMenuButton && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14133
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: `flex items-center justify-between px-6 lg:px-8 ${flat ? "h-[64px]" : "h-[72px]"}`, children: [
14134
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex items-center gap-5", children: [
14135
+ showMobileMenuButton && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12654
14136
  "button",
12655
14137
  {
12656
14138
  type: "button",
@@ -12662,12 +14144,12 @@ function ITTopBar({
12662
14144
  onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "var(--it-topbar-user-hover, #f1f5f9)",
12663
14145
  onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
12664
14146
  onClick: onToggleMobileMenu,
12665
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_fa32.FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
14147
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_fa32.FaBars, { className: "w-[1.125rem] h-[1.125rem]" })
12666
14148
  }
12667
14149
  ),
12668
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: `items-center gap-3 ${hideBrandOnDesktop ? "flex lg:hidden" : "flex"}`, children: [
12669
- logo && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "flex-shrink-0 drop-shadow-sm", children: logo }),
12670
- logoText && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14150
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: `items-center gap-3 ${hideBrandOnDesktop ? "flex lg:hidden" : "flex"}`, children: [
14151
+ logo && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "flex-shrink-0 drop-shadow-sm", children: logo }),
14152
+ logoText && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12671
14153
  ITText,
12672
14154
  {
12673
14155
  as: "span",
@@ -12677,7 +14159,7 @@ function ITTopBar({
12677
14159
  }
12678
14160
  )
12679
14161
  ] }),
12680
- navItems && navItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("nav", { className: "hidden md:flex ml-8 space-x-1 border-l pl-8", style: { borderColor: "var(--it-topbar-border, rgba(15, 23, 42, 0.06))" }, children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14162
+ navItems && navItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("nav", { className: "hidden md:flex ml-8 space-x-1 border-l pl-8", style: { borderColor: "var(--it-topbar-border, rgba(15, 23, 42, 0.06))" }, children: navItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12681
14163
  "button",
12682
14164
  {
12683
14165
  onClick: () => onNavItemClick?.(item.id),
@@ -12691,19 +14173,19 @@ function ITTopBar({
12691
14173
  e.currentTarget.style.color = "var(--it-topbar-text, #475569)";
12692
14174
  e.currentTarget.style.backgroundColor = "transparent";
12693
14175
  },
12694
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-center gap-2", children: [
12695
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "opacity-70", children: item.icon }),
12696
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(ITText, { as: "span", children: item.label })
14176
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex items-center gap-2", children: [
14177
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "opacity-70", children: item.icon }),
14178
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(ITText, { as: "span", children: item.label })
12697
14179
  ] })
12698
14180
  },
12699
14181
  item.id
12700
14182
  )) })
12701
14183
  ] }),
12702
- centerContent && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: `hidden lg:flex flex-1 min-w-0 items-center ${hideBrandOnDesktop ? "justify-start pr-4" : "justify-center px-4"}`, children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "w-full max-w-[420px]", children: centerContent }) }),
12703
- (children || userMenu) && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-center gap-2", children: [
14184
+ centerContent && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: `hidden lg:flex flex-1 min-w-0 items-center ${hideBrandOnDesktop ? "justify-start pr-4" : "justify-center px-4"}`, children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "w-full max-w-[420px]", children: centerContent }) }),
14185
+ (children || userMenu) && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex items-center gap-2", children: [
12704
14186
  children,
12705
- userMenu && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "relative", children: [
12706
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
14187
+ userMenu && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "relative", children: [
14188
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
12707
14189
  "button",
12708
14190
  {
12709
14191
  type: "button",
@@ -12719,15 +14201,15 @@ function ITTopBar({
12719
14201
  },
12720
14202
  onClick: () => setIsUserMenuOpen(!isUserMenuOpen),
12721
14203
  children: [
12722
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "relative", children: [
12723
- userMenu.userImage ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14204
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "relative", children: [
14205
+ userMenu.userImage ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12724
14206
  "img",
12725
14207
  {
12726
14208
  className: "w-9 h-9 rounded-full object-cover ring-2 ring-white shadow-sm",
12727
14209
  src: userMenu.userImage,
12728
14210
  alt: t("common.userAvatar")
12729
14211
  }
12730
- ) : flat && initials ? /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14212
+ ) : flat && initials ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12731
14213
  "div",
12732
14214
  {
12733
14215
  "aria-hidden": "true",
@@ -12738,11 +14220,11 @@ function ITTopBar({
12738
14220
  },
12739
14221
  children: initials
12740
14222
  }
12741
- ) : /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_fa32.FaUserCircle, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
12742
- !flat && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
14223
+ ) : /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "w-9 h-9 rounded-full bg-slate-100 flex items-center justify-center ring-2 ring-white shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(import_fa32.FaUserCircle, { className: "w-6 h-6", style: { color: "var(--it-topbar-icon, #94a3b8)" } }) }),
14224
+ !flat && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "absolute bottom-0 right-0 w-2.5 h-2.5 bg-green-500 border-2 border-white rounded-full" })
12743
14225
  ] }),
12744
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: `hidden sm:flex flex-col py-0.5 ${flat ? "text-right" : "text-left"}`, children: [
12745
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14226
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: `hidden sm:flex flex-col py-0.5 ${flat ? "text-right" : "text-left"}`, children: [
14227
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12746
14228
  ITText,
12747
14229
  {
12748
14230
  as: "span",
@@ -12751,7 +14233,7 @@ function ITTopBar({
12751
14233
  children: userMenu.userName
12752
14234
  }
12753
14235
  ),
12754
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14236
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12755
14237
  ITText,
12756
14238
  {
12757
14239
  as: "span",
@@ -12764,7 +14246,7 @@ function ITTopBar({
12764
14246
  ]
12765
14247
  }
12766
14248
  ),
12767
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
14249
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
12768
14250
  "div",
12769
14251
  {
12770
14252
  ref: userMenuRef,
@@ -12777,15 +14259,15 @@ function ITTopBar({
12777
14259
  border: "1px solid var(--it-topbar-user-dropdown-border, #f1f5f9)"
12778
14260
  },
12779
14261
  children: [
12780
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "px-5 py-4 border-b", style: { borderColor: "var(--it-topbar-user-dropdown-border, #f1f5f9)", backgroundColor: "var(--it-topbar-user-bg, #f8fafc)" }, children: [
12781
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
12782
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
14262
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "px-5 py-4 border-b", style: { borderColor: "var(--it-topbar-user-dropdown-border, #f1f5f9)", backgroundColor: "var(--it-topbar-user-bg, #f8fafc)" }, children: [
14263
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(ITText, { as: "span", className: "block font-bold text-[0.9rem]", style: { color: "var(--it-topbar-user-text, #0f172a)" }, children: userMenu.userName }),
14264
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(ITText, { as: "span", className: "block text-xs font-medium truncate mt-0.5", style: { color: "var(--it-topbar-user-subtitle, #64748b)" }, children: userMenu.userEmail })
12783
14265
  ] }),
12784
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
14266
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("ul", { className: "py-2", children: userMenu.menuItems.map((m, i) => {
12785
14267
  const isDestructive = m.label.toLowerCase().includes("salir") || m.label.toLowerCase().includes("cerrar") || m.label.toLowerCase().includes("logout");
12786
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("li", { className: "px-2", children: [
12787
- i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
12788
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
14268
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("li", { className: "px-2", children: [
14269
+ i === userMenu.menuItems.length - 1 && isDestructive && i > 0 && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "h-px bg-slate-100 my-1 mx-2" }),
14270
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12789
14271
  "button",
12790
14272
  {
12791
14273
  onClick: () => {
@@ -12800,7 +14282,7 @@ function ITTopBar({
12800
14282
  onMouseLeave: (e) => {
12801
14283
  e.currentTarget.style.backgroundColor = "transparent";
12802
14284
  },
12803
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(ITText, { as: "span", children: m.label })
14285
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(ITText, { as: "span", children: m.label })
12804
14286
  }
12805
14287
  )
12806
14288
  ] }, i);
@@ -12816,7 +14298,7 @@ function ITTopBar({
12816
14298
  }
12817
14299
 
12818
14300
  // src/components/templates/layout/layout.tsx
12819
- var import_jsx_runtime76 = require("react/jsx-runtime");
14301
+ var import_jsx_runtime78 = require("react/jsx-runtime");
12820
14302
  function ITLayout({
12821
14303
  topBar,
12822
14304
  sidebar,
@@ -12825,8 +14307,8 @@ function ITLayout({
12825
14307
  contentClassName = "",
12826
14308
  sidebarFullHeight = false
12827
14309
  }) {
12828
- const [internalCollapsed, setInternalCollapsed] = (0, import_react53.useState)(true);
12829
- const [mobileSidebarOpen, setMobileSidebarOpen] = (0, import_react53.useState)(false);
14310
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react56.useState)(true);
14311
+ const [mobileSidebarOpen, setMobileSidebarOpen] = (0, import_react56.useState)(false);
12830
14312
  const flat = useITFlatAppearance();
12831
14313
  const isControlled = sidebar.isCollapsed !== void 0;
12832
14314
  const desktopCollapsed = isControlled ? sidebar.isCollapsed : internalCollapsed;
@@ -12840,7 +14322,7 @@ function ITLayout({
12840
14322
  else setMobileSidebarOpen((v) => !v);
12841
14323
  };
12842
14324
  const brand = sidebarFullHeight ? sidebar.brand ?? { logo: topBar.logo, text: topBar.logoText } : sidebar.brand;
12843
- const topBarNode = /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
14325
+ const topBarNode = /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
12844
14326
  ITTopBar,
12845
14327
  {
12846
14328
  ...topBar,
@@ -12853,9 +14335,9 @@ function ITLayout({
12853
14335
  const desktopSidebar = (
12854
14336
  // Full-height: the sidebar sits beside the top bar, so it needs to win the
12855
14337
  // stacking order when the collapsed rail expands over the content on hover.
12856
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `hidden lg:block relative h-full ${sidebarFullHeight ? "z-50" : "z-40"}`, children: [
12857
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: `${reservedWidth} h-full flex-shrink-0` }),
12858
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
14338
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `hidden lg:block relative h-full ${sidebarFullHeight ? "z-50" : "z-40"}`, children: [
14339
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: `${reservedWidth} h-full flex-shrink-0` }),
14340
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "absolute top-0 left-0 h-full", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
12859
14341
  ITSidebar,
12860
14342
  {
12861
14343
  ...sidebar,
@@ -12868,17 +14350,17 @@ function ITLayout({
12868
14350
  ) })
12869
14351
  ] })
12870
14352
  );
12871
- const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
14353
+ const mobileSidebar = mobileSidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
12872
14354
  "div",
12873
14355
  {
12874
14356
  className: "lg:hidden fixed inset-0 z-[40] transition-opacity duration-300 backdrop-blur-sm bg-black/40",
12875
14357
  onClick: () => setMobileSidebarOpen(false),
12876
- children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
14358
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
12877
14359
  "div",
12878
14360
  {
12879
14361
  className: "h-full w-fit flex transform transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)]",
12880
14362
  onClick: (e) => e.stopPropagation(),
12881
- children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
14363
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
12882
14364
  ITSidebar,
12883
14365
  {
12884
14366
  ...sidebar,
@@ -12895,16 +14377,16 @@ function ITLayout({
12895
14377
  )
12896
14378
  }
12897
14379
  );
12898
- const main = /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("main", { className: "flex-1 overflow-y-auto w-full custom-scrollbar relative z-0", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: (0, import_clsx55.default)("mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8 py-6 h-full", contentClassName), children }) });
14380
+ const main = /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto w-full custom-scrollbar relative z-0", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: (0, import_clsx55.default)("mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8 py-6 h-full", contentClassName), children }) });
12899
14381
  if (sidebarFullHeight) {
12900
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
14382
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
12901
14383
  "div",
12902
14384
  {
12903
14385
  className: `flex h-screen overflow-hidden w-full relative ${className}`,
12904
14386
  style: { backgroundColor: layoutTokens.backgroundColor },
12905
14387
  children: [
12906
14388
  desktopSidebar,
12907
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex flex-col flex-1 min-w-0 overflow-hidden", children: [
14389
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col flex-1 min-w-0 overflow-hidden", children: [
12908
14390
  topBarNode,
12909
14391
  main
12910
14392
  ] }),
@@ -12913,9 +14395,9 @@ function ITLayout({
12913
14395
  }
12914
14396
  );
12915
14397
  }
12916
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `flex flex-col h-screen overflow-hidden w-full ${className}`, children: [
14398
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `flex flex-col h-screen overflow-hidden w-full ${className}`, children: [
12917
14399
  topBarNode,
12918
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
14400
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
12919
14401
  "div",
12920
14402
  {
12921
14403
  className: "flex flex-1 overflow-hidden relative",
@@ -12930,97 +14412,11 @@ function ITLayout({
12930
14412
  ] });
12931
14413
  }
12932
14414
 
12933
- // src/types/loader.types.ts
12934
- var sizeClasses = {
12935
- sm: "h-4 w-4",
12936
- md: "h-8 w-8",
12937
- lg: "h-12 w-12",
12938
- xl: "h-16 w-16"
12939
- };
12940
-
12941
- // src/components/atoms/loader/loader.tsx
12942
- var import_jsx_runtime77 = require("react/jsx-runtime");
12943
- function ITLoader({
12944
- size = "md",
12945
- variant = "spinner",
12946
- color = "primary",
12947
- // Default to semantic primary
12948
- className = ""
12949
- }) {
12950
- const { t } = useITTranslation();
12951
- const isSemantic = color in theme.colors;
12952
- const resolvedColor = isSemantic ? theme.colors[color][500] : color;
12953
- const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
12954
- const style = isCssValue ? { color: resolvedColor } : {};
12955
- const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
12956
- const colorClass = !isCssValue ? color : "";
12957
- if (variant === "spinner") {
12958
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12959
- "div",
12960
- {
12961
- className: `inline-block ${sizeClasses[size]} animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${colorClass} ${className}`,
12962
- role: "status",
12963
- style,
12964
- children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(ITText, { as: "span", className: "!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]", children: t("common.loading") })
12965
- }
12966
- );
12967
- }
12968
- if (variant === "dots") {
12969
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12970
- "div",
12971
- {
12972
- className: `flex items-center justify-center space-x-2 ${className}`,
12973
- children: [...Array(3)].map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12974
- "div",
12975
- {
12976
- className: `${sizeClasses[size.replace(/l|g/, "")]} animate-bounce rounded-full ${colorClass}`,
12977
- style: {
12978
- ...bgStyle,
12979
- animationDelay: `${i * 0.1}s`
12980
- }
12981
- },
12982
- i
12983
- ))
12984
- }
12985
- );
12986
- }
12987
- if (variant === "bar") {
12988
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12989
- "div",
12990
- {
12991
- className: `w-full ${size === "sm" ? "h-1" : size === "md" ? "h-1.5" : size === "lg" ? "h-2" : "h-2.5"} bg-secondary-200 rounded-full overflow-hidden ${className}`,
12992
- children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
12993
- "div",
12994
- {
12995
- className: `h-full animate-progress ${colorClass}`,
12996
- style: {
12997
- backgroundColor: resolvedColor,
12998
- // Simplified gradient for modern look, or keep it solid
12999
- backgroundImage: isCssValue ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})` : void 0,
13000
- animation: "progress 1.5s ease-in-out infinite"
13001
- }
13002
- }
13003
- )
13004
- }
13005
- );
13006
- }
13007
- if (variant === "pulse") {
13008
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
13009
- "div",
13010
- {
13011
- className: `rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`,
13012
- style: bgStyle
13013
- }
13014
- );
13015
- }
13016
- return null;
13017
- }
13018
-
13019
14415
  // src/components/molecules/stepper/stepper.tsx
13020
14416
  var import_clsx56 = __toESM(require("clsx"), 1);
13021
- var import_react54 = require("react");
14417
+ var import_react57 = require("react");
13022
14418
  var import_fa33 = require("react-icons/fa");
13023
- var import_jsx_runtime78 = require("react/jsx-runtime");
14419
+ var import_jsx_runtime79 = require("react/jsx-runtime");
13024
14420
  function ITStepper({
13025
14421
  steps,
13026
14422
  currentStep,
@@ -13036,15 +14432,15 @@ function ITStepper({
13036
14432
  color = "primary"
13037
14433
  }) {
13038
14434
  const { t } = useITTranslation();
13039
- const [direction, setDirection] = (0, import_react54.useState)("next");
13040
- const contentRef = (0, import_react54.useRef)(null);
13041
- const progressRef = (0, import_react54.useRef)(null);
14435
+ const [direction, setDirection] = (0, import_react57.useState)("next");
14436
+ const contentRef = (0, import_react57.useRef)(null);
14437
+ const progressRef = (0, import_react57.useRef)(null);
13042
14438
  const isThemeColor = color in theme.colors;
13043
14439
  const resolvedColor = isThemeColor ? theme.colors[color][500] : color;
13044
- (0, import_react54.useEffect)(() => {
14440
+ (0, import_react57.useEffect)(() => {
13045
14441
  onStepChange?.(currentStep);
13046
14442
  }, [currentStep, onStepChange]);
13047
- (0, import_react54.useEffect)(() => {
14443
+ (0, import_react57.useEffect)(() => {
13048
14444
  const pct = currentStep / Math.max(1, steps.length - 1) * 100;
13049
14445
  if (progressRef.current) {
13050
14446
  progressRef.current.style.width = `${pct}%`;
@@ -13088,23 +14484,23 @@ function ITStepper({
13088
14484
  const renderStepContent = (index, isCompleted) => {
13089
14485
  const step = steps[index];
13090
14486
  if (isCompleted) {
13091
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_fa33.FaCheck, { className: "w-4 h-4" });
14487
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_fa33.FaCheck, { className: "w-4 h-4" });
13092
14488
  }
13093
14489
  if (step.icon && useIcons) {
13094
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
14490
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex items-center justify-center w-5 h-5", children: step.icon });
13095
14491
  }
13096
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
14492
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-sm font-semibold", children: index + 1 });
13097
14493
  };
13098
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: (0, import_clsx56.default)("w-full max-w-5xl mx-auto px-4", containerClassName), children: [
13099
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "relative mb-8", children: [
13100
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14494
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: (0, import_clsx56.default)("w-full max-w-5xl mx-auto px-4", containerClassName), children: [
14495
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "relative mb-8", children: [
14496
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13101
14497
  "div",
13102
14498
  {
13103
14499
  className: "absolute left-6 right-6 top-5 h-1 bg-secondary-200 rounded-full z-0",
13104
14500
  "aria-hidden": true
13105
14501
  }
13106
14502
  ),
13107
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14503
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13108
14504
  "div",
13109
14505
  {
13110
14506
  ref: progressRef,
@@ -13112,11 +14508,11 @@ function ITStepper({
13112
14508
  "aria-hidden": true
13113
14509
  }
13114
14510
  ),
13115
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
14511
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex items-start justify-between space-x-2 relative z-20", children: steps.map((step, idx) => {
13116
14512
  const isActive = idx === currentStep;
13117
14513
  const isCompleted = idx < currentStep;
13118
14514
  const hasIcon = step.icon && useIcons;
13119
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14515
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13120
14516
  "button",
13121
14517
  {
13122
14518
  type: "button",
@@ -13126,8 +14522,8 @@ function ITStepper({
13126
14522
  "aria-label": t("stepper.stepAria", { n: idx + 1, label: step.label }),
13127
14523
  className: "flex-1 group",
13128
14524
  title: step.label,
13129
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col items-center", children: [
13130
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14525
+ children: /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex flex-col items-center", children: [
14526
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13131
14527
  "div",
13132
14528
  {
13133
14529
  className: (0, import_clsx56.default)(
@@ -13141,7 +14537,7 @@ function ITStepper({
13141
14537
  children: renderStepContent(idx, isCompleted)
13142
14538
  }
13143
14539
  ),
13144
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14540
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13145
14541
  ITText,
13146
14542
  {
13147
14543
  as: "span",
@@ -13159,7 +14555,7 @@ function ITStepper({
13159
14555
  );
13160
14556
  }) })
13161
14557
  ] }),
13162
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14558
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13163
14559
  "div",
13164
14560
  {
13165
14561
  ref: contentRef,
@@ -13175,32 +14571,32 @@ function ITStepper({
13175
14571
  children: steps[currentStep].content
13176
14572
  }
13177
14573
  ),
13178
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex justify-between items-center mt-6", children: [
13179
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14574
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex justify-between items-center mt-6", children: [
14575
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13180
14576
  ITButton,
13181
14577
  {
13182
14578
  variant: "outlined",
13183
14579
  color: "secondary",
13184
14580
  disabled: currentStep === 0,
13185
14581
  onClick: prevStep,
13186
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex items-center gap-2", children: [
13187
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_fa33.FaChevronLeft, {}),
13188
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ITText, { as: "span", children: t("common.back") })
14582
+ children: /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-2", children: [
14583
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_fa33.FaChevronLeft, {}),
14584
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", children: t("common.back") })
13189
14585
  ] })
13190
14586
  }
13191
14587
  ),
13192
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex items-center gap-3", children: [
13193
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ITText, { as: "div", className: "text-sm text-secondary-500 mr-2 hidden sm:block", children: t("stepper.stepOf", { current: currentStep + 1, total: steps.length }) }),
13194
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
14588
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-3", children: [
14589
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "div", className: "text-sm text-secondary-500 mr-2 hidden sm:block", children: t("stepper.stepOf", { current: currentStep + 1, total: steps.length }) }),
14590
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
13195
14591
  ITButton,
13196
14592
  {
13197
14593
  variant: "solid",
13198
14594
  color,
13199
14595
  disabled: disableNext,
13200
14596
  onClick: nextStep,
13201
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex items-center gap-2", children: [
13202
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ITText, { as: "span", children: currentStep === steps.length - 1 ? t("common.finish") : t("common.next") }),
13203
- currentStep === steps.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_fa33.FaCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_fa33.FaChevronRight, {})
14597
+ children: /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-2", children: [
14598
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", children: currentStep === steps.length - 1 ? t("common.finish") : t("common.next") }),
14599
+ currentStep === steps.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_fa33.FaCheck, {}) : /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_fa33.FaChevronRight, {})
13204
14600
  ] })
13205
14601
  }
13206
14602
  )
@@ -13210,7 +14606,7 @@ function ITStepper({
13210
14606
  }
13211
14607
 
13212
14608
  // src/components/theme-provider/themeProvider.tsx
13213
- var import_react55 = require("react");
14609
+ var import_react58 = require("react");
13214
14610
  var import_md3 = require("react-icons/md");
13215
14611
 
13216
14612
  // src/components/theme-provider/themePresets.ts
@@ -13388,7 +14784,7 @@ var PRESETS = [
13388
14784
  ];
13389
14785
 
13390
14786
  // src/components/theme-provider/themeProvider.tsx
13391
- var import_jsx_runtime79 = require("react/jsx-runtime");
14787
+ var import_jsx_runtime80 = require("react/jsx-runtime");
13392
14788
  var STORAGE_KEY = "it-theme-palette";
13393
14789
  var SHADOW_LEVELS = {
13394
14790
  0: {
@@ -13491,7 +14887,7 @@ function ITThemeProvider({
13491
14887
  appearance = "soft"
13492
14888
  }) {
13493
14889
  const { t } = useITTranslation();
13494
- const [palette2, setPaletteState] = (0, import_react55.useState)(() => {
14890
+ const [palette2, setPaletteState] = (0, import_react58.useState)(() => {
13495
14891
  const basePalette = {
13496
14892
  ...DEFAULT_PALETTE,
13497
14893
  ...theme2,
@@ -13517,8 +14913,8 @@ function ITThemeProvider({
13517
14913
  }
13518
14914
  return basePalette;
13519
14915
  });
13520
- const [isOpen, setIsOpen] = (0, import_react55.useState)(false);
13521
- const [customPresets, setCustomPresets] = (0, import_react55.useState)(() => {
14916
+ const [isOpen, setIsOpen] = (0, import_react58.useState)(false);
14917
+ const [customPresets, setCustomPresets] = (0, import_react58.useState)(() => {
13522
14918
  try {
13523
14919
  const saved = localStorage.getItem("it-theme-custom-presets");
13524
14920
  return saved ? JSON.parse(saved) : [];
@@ -13527,8 +14923,8 @@ function ITThemeProvider({
13527
14923
  return [];
13528
14924
  }
13529
14925
  });
13530
- const [newPresetName, setNewPresetName] = (0, import_react55.useState)("");
13531
- const [isSavingPreset, setIsSavingPreset] = (0, import_react55.useState)(false);
14926
+ const [newPresetName, setNewPresetName] = (0, import_react58.useState)("");
14927
+ const [isSavingPreset, setIsSavingPreset] = (0, import_react58.useState)(false);
13532
14928
  const handleSavePreset = () => {
13533
14929
  if (!newPresetName.trim()) return;
13534
14930
  const newPreset = {
@@ -13547,8 +14943,8 @@ function ITThemeProvider({
13547
14943
  setCustomPresets(updated);
13548
14944
  localStorage.setItem("it-theme-custom-presets", JSON.stringify(updated));
13549
14945
  };
13550
- const [resolvedTheme, setResolvedTheme] = (0, import_react55.useState)("light");
13551
- const [darkModeMode, setDarkModeMode] = (0, import_react55.useState)(
14946
+ const [resolvedTheme, setResolvedTheme] = (0, import_react58.useState)("light");
14947
+ const [darkModeMode, setDarkModeMode] = (0, import_react58.useState)(
13552
14948
  () => {
13553
14949
  const saved = localStorage.getItem("it-theme-dark-mode");
13554
14950
  if (saved === "light" || saved === "dark" || saved === "system") {
@@ -13557,7 +14953,7 @@ function ITThemeProvider({
13557
14953
  return "system";
13558
14954
  }
13559
14955
  );
13560
- (0, import_react55.useEffect)(() => {
14956
+ (0, import_react58.useEffect)(() => {
13561
14957
  localStorage.setItem("it-theme-dark-mode", darkModeMode);
13562
14958
  const applyDarkMode = (isDark) => {
13563
14959
  if (isDark) {
@@ -13582,7 +14978,7 @@ function ITThemeProvider({
13582
14978
  applyDarkMode(darkModeMode === "dark");
13583
14979
  }
13584
14980
  }, [darkModeMode]);
13585
- (0, import_react55.useEffect)(() => {
14981
+ (0, import_react58.useEffect)(() => {
13586
14982
  if (!showFab) {
13587
14983
  setPaletteState({
13588
14984
  ...DEFAULT_PALETTE,
@@ -13592,7 +14988,7 @@ function ITThemeProvider({
13592
14988
  });
13593
14989
  }
13594
14990
  }, [theme2, showFab]);
13595
- (0, import_react55.useLayoutEffect)(() => {
14991
+ (0, import_react58.useLayoutEffect)(() => {
13596
14992
  const root = document.documentElement;
13597
14993
  const scale = typeof density === "number" && isFinite(density) ? Math.min(Math.max(density, 0.5), 1.5) : 1;
13598
14994
  root.style.setProperty("--it-density", String(scale));
@@ -13602,12 +14998,12 @@ function ITThemeProvider({
13602
14998
  root.style.fontSize = "";
13603
14999
  };
13604
15000
  }, [density]);
13605
- (0, import_react55.useLayoutEffect)(() => {
15001
+ (0, import_react58.useLayoutEffect)(() => {
13606
15002
  const root = document.documentElement;
13607
15003
  root.setAttribute("data-it-appearance", appearance);
13608
15004
  return () => root.removeAttribute("data-it-appearance");
13609
15005
  }, [appearance]);
13610
- (0, import_react55.useLayoutEffect)(() => {
15006
+ (0, import_react58.useLayoutEffect)(() => {
13611
15007
  const root = document.documentElement;
13612
15008
  const radiusTokens = ["xs", "sm", "md", "lg", "xl", "2xl", "3xl"];
13613
15009
  if (typeof radius === "number" && isFinite(radius)) {
@@ -13639,7 +15035,7 @@ function ITThemeProvider({
13639
15035
  surfaceStyle?.remove();
13640
15036
  };
13641
15037
  }, [radius, shadow]);
13642
- (0, import_react55.useEffect)(() => {
15038
+ (0, import_react58.useEffect)(() => {
13643
15039
  const injectStyles = (obj, prefix = "") => {
13644
15040
  Object.entries(obj).forEach(([key, val]) => {
13645
15041
  if (typeof val === "object" && val !== null) {
@@ -14793,14 +16189,14 @@ function ITThemeProvider({
14793
16189
  const isNested = colorKey.includes(".");
14794
16190
  const label = isNested ? colorKey.split(".")[1] : colorKey;
14795
16191
  const value = getNestedValue3(palette2, colorKey);
14796
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
16192
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
14797
16193
  "div",
14798
16194
  {
14799
16195
  className: "flex items-center justify-between p-3 rounded-xl border border-slate-100 dark:border-slate-800 bg-white dark:bg-slate-900/50 gap-3 hover:border-slate-200 dark:hover:border-slate-700 transition-colors",
14800
16196
  children: [
14801
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
14802
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "relative w-10 h-10 rounded-xl border-2 border-slate-200 dark:border-slate-700 overflow-hidden cursor-pointer flex-shrink-0 shadow-sm hover:scale-105 transition-transform", children: [
14803
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16197
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center gap-3 flex-1 min-w-0", children: [
16198
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "relative w-10 h-10 rounded-xl border-2 border-slate-200 dark:border-slate-700 overflow-hidden cursor-pointer flex-shrink-0 shadow-sm hover:scale-105 transition-transform", children: [
16199
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14804
16200
  "input",
14805
16201
  {
14806
16202
  type: "color",
@@ -14809,23 +16205,23 @@ function ITThemeProvider({
14809
16205
  className: "absolute inset-0 opacity-0 cursor-pointer w-full h-full"
14810
16206
  }
14811
16207
  ),
14812
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "w-full h-full", style: { backgroundColor: value } })
16208
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "w-full h-full", style: { backgroundColor: value } })
14813
16209
  ] }),
14814
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex flex-col min-w-0", children: [
14815
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-xs font-bold text-slate-700 dark:text-slate-300 truncate capitalize", children: label.replace(/([A-Z])/g, " $1").trim() }),
14816
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
14817
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16210
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex flex-col min-w-0", children: [
16211
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "text-xs font-bold text-slate-700 dark:text-slate-300 truncate capitalize", children: label.replace(/([A-Z])/g, " $1").trim() }),
16212
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
16213
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14818
16214
  "span",
14819
16215
  {
14820
16216
  className: "w-3 h-3 rounded-full border border-slate-200 dark:border-slate-600",
14821
16217
  style: { backgroundColor: value }
14822
16218
  }
14823
16219
  ),
14824
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
16220
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "font-mono text-[11px] text-slate-400", children: value })
14825
16221
  ] })
14826
16222
  ] })
14827
16223
  ] }),
14828
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16224
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14829
16225
  "input",
14830
16226
  {
14831
16227
  type: "text",
@@ -14844,14 +16240,14 @@ function ITThemeProvider({
14844
16240
  isCustom
14845
16241
  }) => {
14846
16242
  const isSelected = JSON.stringify(preset.colors) === JSON.stringify(palette2);
14847
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
16243
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
14848
16244
  "button",
14849
16245
  {
14850
16246
  type: "button",
14851
16247
  onClick: () => applyPreset(preset.colors),
14852
16248
  className: `relative flex flex-col items-start p-2.5 rounded-xl border text-left transition-all group ${isSelected ? "border-primary-500 bg-primary-500/5 shadow-sm ring-1 ring-primary-500/20" : "border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50 hover:border-slate-300 dark:hover:border-slate-600"}`,
14853
16249
  children: [
14854
- isCustom && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16250
+ isCustom && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14855
16251
  "span",
14856
16252
  {
14857
16253
  onClick: (e) => {
@@ -14860,11 +16256,11 @@ function ITThemeProvider({
14860
16256
  },
14861
16257
  className: "absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 p-0.5 rounded-md hover:bg-danger-500/10 hover:text-danger-500 text-slate-400 dark:text-slate-500 cursor-pointer transition-all z-10",
14862
16258
  title: t("themeProvider.designer.deletePreset"),
14863
- children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_md3.MdClose, { size: 12 })
16259
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_md3.MdClose, { size: 12 })
14864
16260
  }
14865
16261
  ),
14866
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-xs font-semibold truncate w-full mb-1.5 pr-4 text-slate-700 dark:text-slate-300", children: PRESET_I18N_KEY[preset.name] ? t(PRESET_I18N_KEY[preset.name]) : preset.name }),
14867
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex gap-1", children: ["primary", "secondary", "ternary", "success"].map((c) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16262
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "text-xs font-semibold truncate w-full mb-1.5 pr-4 text-slate-700 dark:text-slate-300", children: PRESET_I18N_KEY[preset.name] ? t(PRESET_I18N_KEY[preset.name]) : preset.name }),
16263
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "flex gap-1", children: ["primary", "secondary", "ternary", "success"].map((c) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14868
16264
  "span",
14869
16265
  {
14870
16266
  className: "w-3 h-3 rounded-full border border-black/10",
@@ -14876,7 +16272,7 @@ function ITThemeProvider({
14876
16272
  }
14877
16273
  );
14878
16274
  };
14879
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
16275
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
14880
16276
  ITThemeContext.Provider,
14881
16277
  {
14882
16278
  value: {
@@ -14893,28 +16289,28 @@ function ITThemeProvider({
14893
16289
  },
14894
16290
  children: [
14895
16291
  children,
14896
- showFab && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16292
+ showFab && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14897
16293
  "button",
14898
16294
  {
14899
16295
  onClick: () => setIsOpen((prev) => !prev),
14900
16296
  className: "it-theme-fab it-theme-bounce",
14901
16297
  style: { backgroundColor: "var(--color-primary)" },
14902
16298
  "aria-label": t("themeProvider.fab.ariaLabel"),
14903
- children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_md3.MdPalette, { size: 28 })
16299
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_md3.MdPalette, { size: 28 })
14904
16300
  }
14905
16301
  ),
14906
- showFab && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16302
+ showFab && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14907
16303
  ITDialog,
14908
16304
  {
14909
16305
  isOpen,
14910
16306
  onClose: () => setIsOpen(false),
14911
16307
  title: t("themeProvider.designer.title"),
14912
16308
  useFormHeader: true,
14913
- children: /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex gap-6 h-[580px]", children: [
14914
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "w-64 flex-shrink-0 flex flex-col gap-5 overflow-y-auto pr-1", children: [
14915
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { children: [
14916
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.appearance") }),
14917
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16309
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex gap-6 h-[580px]", children: [
16310
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "w-64 flex-shrink-0 flex flex-col gap-5 overflow-y-auto pr-1", children: [
16311
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { children: [
16312
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.appearance") }),
16313
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14918
16314
  ITSegmentedControl,
14919
16315
  {
14920
16316
  options: [
@@ -14928,16 +16324,16 @@ function ITThemeProvider({
14928
16324
  }
14929
16325
  )
14930
16326
  ] }),
14931
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { children: [
14932
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex items-center justify-between mb-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500", children: t("themeProvider.designer.presets") }) }),
14933
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "grid grid-cols-2 gap-2", children: PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(PresetCard, { preset }, preset.name)) })
16327
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { children: [
16328
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "flex items-center justify-between mb-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500", children: t("themeProvider.designer.presets") }) }),
16329
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "grid grid-cols-2 gap-2", children: PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PresetCard, { preset }, preset.name)) })
14934
16330
  ] }),
14935
- customPresets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { children: [
14936
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.myThemes") }),
14937
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex flex-col gap-1.5", children: customPresets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(PresetCard, { preset, isCustom: true }, preset.name)) })
16331
+ customPresets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { children: [
16332
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "span", className: "text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block", children: t("themeProvider.designer.myThemes") }),
16333
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "flex flex-col gap-1.5", children: customPresets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(PresetCard, { preset, isCustom: true }, preset.name)) })
14938
16334
  ] }),
14939
- isSavingPreset && /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex flex-col gap-2 p-3 rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50", children: [
14940
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16335
+ isSavingPreset && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex flex-col gap-2 p-3 rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50", children: [
16336
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14941
16337
  ITInput,
14942
16338
  {
14943
16339
  name: "presetName",
@@ -14955,8 +16351,8 @@ function ITThemeProvider({
14955
16351
  }
14956
16352
  }
14957
16353
  ),
14958
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex gap-2", children: [
14959
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16354
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex gap-2", children: [
16355
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14960
16356
  ITButton,
14961
16357
  {
14962
16358
  label: t("themeProvider.designer.save"),
@@ -14967,7 +16363,7 @@ function ITThemeProvider({
14967
16363
  className: "flex-1"
14968
16364
  }
14969
16365
  ),
14970
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16366
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14971
16367
  ITButton,
14972
16368
  {
14973
16369
  label: t("themeProvider.designer.cancelSave"),
@@ -14981,31 +16377,31 @@ function ITThemeProvider({
14981
16377
  )
14982
16378
  ] })
14983
16379
  ] }),
14984
- !isSavingPreset && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16380
+ !isSavingPreset && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14985
16381
  ITButton,
14986
16382
  {
14987
16383
  variant: "outlined",
14988
- icon: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_md3.MdPalette, { size: 14 }),
16384
+ icon: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_md3.MdPalette, { size: 14 }),
14989
16385
  label: t("themeProvider.designer.saveCurrent"),
14990
16386
  onClick: () => setIsSavingPreset(true),
14991
16387
  size: "sm"
14992
16388
  }
14993
16389
  ),
14994
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16390
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
14995
16391
  ITButton,
14996
16392
  {
14997
16393
  variant: "outlined",
14998
16394
  color: "danger",
14999
- icon: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(import_md3.MdRefresh, { size: 14 }),
16395
+ icon: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_md3.MdRefresh, { size: 14 }),
15000
16396
  label: t("themeProvider.designer.reset"),
15001
16397
  onClick: resetTheme,
15002
16398
  size: "sm"
15003
16399
  }
15004
16400
  )
15005
16401
  ] }),
15006
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITDivider, { orientation: "vertical" }),
15007
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex-1 flex flex-col min-w-0", children: [
15008
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16402
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITDivider, { orientation: "vertical" }),
16403
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex-1 flex flex-col min-w-0", children: [
16404
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
15009
16405
  tabs_default,
15010
16406
  {
15011
16407
  variant: "pill",
@@ -15013,7 +16409,7 @@ function ITThemeProvider({
15013
16409
  {
15014
16410
  id: "brand",
15015
16411
  label: t("themeProvider.tabs.brand"),
15016
- content: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16412
+ content: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
15017
16413
  "primary",
15018
16414
  "secondary",
15019
16415
  "ternary",
@@ -15022,35 +16418,35 @@ function ITThemeProvider({
15022
16418
  "info",
15023
16419
  "alert",
15024
16420
  "warning"
15025
- ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ColorRow, { colorKey: key }, key)) })
16421
+ ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ColorRow, { colorKey: key }, key)) })
15026
16422
  },
15027
16423
  {
15028
16424
  id: "layout",
15029
16425
  label: t("themeProvider.tabs.layout"),
15030
- content: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16426
+ content: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
15031
16427
  "layout.sidebarBg",
15032
16428
  "layout.sidebarText",
15033
16429
  "layout.navbarBg",
15034
16430
  "layout.navbarText"
15035
- ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ColorRow, { colorKey: key }, key)) })
16431
+ ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ColorRow, { colorKey: key }, key)) })
15036
16432
  },
15037
16433
  {
15038
16434
  id: "tables",
15039
16435
  label: t("themeProvider.tabs.tables"),
15040
- content: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
16436
+ content: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3", children: [
15041
16437
  "table.headerBg",
15042
16438
  "table.headerText",
15043
16439
  "table.rowBg",
15044
16440
  "table.rowText",
15045
16441
  "table.rowHover"
15046
- ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ColorRow, { colorKey: key }, key)) })
16442
+ ].map((key) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ColorRow, { colorKey: key }, key)) })
15047
16443
  }
15048
16444
  ]
15049
16445
  }
15050
16446
  ),
15051
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "flex items-center justify-end gap-3 mt-auto pt-4 border-t border-slate-100 dark:border-slate-800", children: [
15052
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ITText, { as: "p", className: "text-[11px] text-slate-400 mr-auto", children: t("themeProvider.designer.autosave") }),
15053
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
16447
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center justify-end gap-3 mt-auto pt-4 border-t border-slate-100 dark:border-slate-800", children: [
16448
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ITText, { as: "p", className: "text-[11px] text-slate-400 mr-auto", children: t("themeProvider.designer.autosave") }),
16449
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
15054
16450
  ITButton,
15055
16451
  {
15056
16452
  label: t("themeProvider.designer.close"),
@@ -15081,7 +16477,13 @@ var createValidationSchema = (fields) => Yup.object().shape(
15081
16477
  );
15082
16478
  // Annotate the CommonJS export names for ESM import in node:
15083
16479
  0 && (module.exports = {
16480
+ AXZY_CATALOG_ENTRIES,
16481
+ AXZY_EXCLUDED_TYPES,
16482
+ CURRENT_SCHEMA_VERSION,
16483
+ DEFAULT_LIMITS,
16484
+ DEFAULT_MIGRATIONS,
15084
16485
  FileTypeEnum,
16486
+ GLOBALLY_FORBIDDEN_PROPS,
15085
16487
  ITAccordion,
15086
16488
  ITAlert,
15087
16489
  ITAvatar,
@@ -15125,6 +16527,7 @@ var createValidationSchema = (fields) => Yup.object().shape(
15125
16527
  ITPopover,
15126
16528
  ITProgress,
15127
16529
  ITRadioGroup,
16530
+ ITSchemaRenderer,
15128
16531
  ITSearchSelect,
15129
16532
  ITSearchTable,
15130
16533
  ITSegmentedControl,
@@ -15145,13 +16548,39 @@ var createValidationSchema = (fields) => Yup.object().shape(
15145
16548
  ITToast,
15146
16549
  ITTripleFilter,
15147
16550
  ITWysiwyg,
16551
+ JsonEngineError,
16552
+ NodeBoundary,
15148
16553
  UploadStatus,
16554
+ auditTree,
16555
+ axzyCatalog,
16556
+ axzyCatalogTypes,
16557
+ buildVocabularyContract,
16558
+ countPendingNodes,
16559
+ createCatalog,
16560
+ createLimitTracker,
15149
16561
  createValidationSchema,
15150
16562
  enMessages,
15151
16563
  esMessages,
16564
+ formatPath,
16565
+ formatVocabularyForPrompt,
16566
+ getCatalogEntry,
15152
16567
  getContrastTextColor,
16568
+ getExclusionReason,
16569
+ hasPath,
16570
+ isExcludedType,
15153
16571
  isLightColor,
16572
+ isNodePending,
16573
+ issue,
16574
+ migrateSchema,
16575
+ parsePartialSchema,
16576
+ parsePath,
16577
+ propPath,
16578
+ pushPath,
16579
+ readPath,
16580
+ renderNode,
15154
16581
  resolveCssColor,
16582
+ resolveLimits,
16583
+ resolveNode,
15155
16584
  useClickOutside,
15156
16585
  useDebouncedSearch,
15157
16586
  useEditableRow,
@@ -15161,6 +16590,7 @@ var createValidationSchema = (fields) => Yup.object().shape(
15161
16590
  useITThemeSafe,
15162
16591
  useITTranslation,
15163
16592
  useJsonRender,
15164
- useTableState
16593
+ useTableState,
16594
+ validateSchema
15165
16595
  });
15166
16596
  //# sourceMappingURL=index.cjs.map