@htlkg/components 0.0.11 → 0.0.13

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 (112) hide show
  1. package/dist/{AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js → AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js} +26 -29
  2. package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js.map +1 -0
  3. package/dist/Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js.map +1 -1
  4. package/dist/DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js.map +1 -1
  5. package/dist/ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js.map +1 -1
  6. package/dist/components.css +4 -4
  7. package/dist/composables/index.js +23 -22
  8. package/dist/data/index.js +10 -10
  9. package/dist/{filterHelpers-DgRyoYSa.js → filterHelpers-DpHSlTuh.js} +11 -11
  10. package/dist/filterHelpers-DpHSlTuh.js.map +1 -0
  11. package/dist/index-QK97OdqQ.js.map +1 -1
  12. package/dist/index.js +34 -33
  13. package/dist/navigation/index.js +1 -1
  14. package/dist/{useAdminPage-GhgXp0x8.js → useAdminPage-AgWRvw6o.js} +150 -26
  15. package/dist/useAdminPage-AgWRvw6o.js.map +1 -0
  16. package/package.json +3 -3
  17. package/src/composables/index.ts +1 -0
  18. package/src/composables/useJsonForm.test.ts +272 -0
  19. package/src/composables/useJsonForm.ts +261 -0
  20. package/src/composables/useModal.test.ts +264 -0
  21. package/src/composables/useModal.ts +54 -8
  22. package/src/data/Chart/index.ts +2 -0
  23. package/src/data/DataList/index.ts +1 -0
  24. package/src/data/{DataTable.vue → DataTable/DataTable.vue} +2 -2
  25. package/src/data/DataTable/index.ts +8 -0
  26. package/src/data/SearchableSelect/index.ts +1 -0
  27. package/src/data/Table/index.ts +1 -0
  28. package/src/data/index.ts +5 -15
  29. package/src/domain/BrandCard/index.ts +1 -0
  30. package/src/domain/BrandSelector/index.ts +1 -0
  31. package/src/domain/ProductBadge/index.ts +1 -0
  32. package/src/domain/UserAvatar/index.ts +1 -0
  33. package/src/domain/index.ts +4 -4
  34. package/src/forms/DateRange/index.ts +2 -0
  35. package/src/forms/JsonSchemaForm/index.ts +1 -0
  36. package/src/forms/index.ts +2 -3
  37. package/src/navigation/{AdminWrapper.vue → AdminWrapper/AdminWrapper.vue} +41 -30
  38. package/src/navigation/AdminWrapper/index.ts +1 -0
  39. package/src/navigation/Breadcrumbs/index.ts +1 -0
  40. package/src/navigation/Stepper/index.ts +2 -0
  41. package/src/navigation/Tabs/index.ts +2 -0
  42. package/src/navigation/index.ts +4 -6
  43. package/src/overlays/Alert/index.ts +1 -0
  44. package/src/overlays/Drawer/index.ts +1 -0
  45. package/src/overlays/Modal/index.ts +1 -0
  46. package/src/overlays/Notification/index.ts +1 -0
  47. package/src/overlays/index.ts +4 -4
  48. package/src/patterns/DASHBOARD_PAGE.md +642 -0
  49. package/src/patterns/DETAIL_PAGE.md +446 -0
  50. package/src/patterns/FORM_PAGE.md +439 -0
  51. package/src/patterns/LIST_PAGE.md +340 -0
  52. package/src/patterns/PAGE_PATTERNS.md +110 -0
  53. package/src/patterns/WIZARD_PAGE.md +733 -0
  54. package/dist/AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map +0 -1
  55. package/dist/filterHelpers-DgRyoYSa.js.map +0 -1
  56. package/dist/useAdminPage-GhgXp0x8.js.map +0 -1
  57. package/src/data/Table.vue +0 -295
  58. /package/src/data/{Chart.demo.vue → Chart/Chart.demo.vue} +0 -0
  59. /package/src/data/{Chart.md → Chart/Chart.md} +0 -0
  60. /package/src/data/{Chart.vue → Chart/Chart.vue} +0 -0
  61. /package/src/data/{DataList.md → DataList/DataList.md} +0 -0
  62. /package/src/data/{DataList.test.ts → DataList/DataList.test.ts} +0 -0
  63. /package/src/data/{DataList.vue → DataList/DataList.vue} +0 -0
  64. /package/src/data/{SearchableSelect.md → SearchableSelect/SearchableSelect.md} +0 -0
  65. /package/src/data/{SearchableSelect.vue → SearchableSelect/SearchableSelect.vue} +0 -0
  66. /package/src/data/{Table.demo.vue → Table/Table.demo.vue} +0 -0
  67. /package/src/data/{Table.md → Table/Table.md} +0 -0
  68. /package/src/data/{Table.property.test.ts → Table/Table.property.test.ts} +0 -0
  69. /package/src/data/{Table.test.ts → Table/Table.test.ts} +0 -0
  70. /package/src/data/{Table.unit.test.ts → Table/Table.unit.test.ts} +0 -0
  71. /package/src/domain/{BrandCard.md → BrandCard/BrandCard.md} +0 -0
  72. /package/src/domain/{BrandCard.vue → BrandCard/BrandCard.vue} +0 -0
  73. /package/src/domain/{BrandSelector.md → BrandSelector/BrandSelector.md} +0 -0
  74. /package/src/domain/{BrandSelector.vue → BrandSelector/BrandSelector.vue} +0 -0
  75. /package/src/domain/{ProductBadge.md → ProductBadge/ProductBadge.md} +0 -0
  76. /package/src/domain/{ProductBadge.vue → ProductBadge/ProductBadge.vue} +0 -0
  77. /package/src/domain/{UserAvatar.md → UserAvatar/UserAvatar.md} +0 -0
  78. /package/src/domain/{UserAvatar.vue → UserAvatar/UserAvatar.vue} +0 -0
  79. /package/src/forms/{DateRange.demo.vue → DateRange/DateRange.demo.vue} +0 -0
  80. /package/src/forms/{DateRange.md → DateRange/DateRange.md} +0 -0
  81. /package/src/forms/{DateRange.vue → DateRange/DateRange.vue} +0 -0
  82. /package/src/forms/{JsonSchemaForm.demo.vue → JsonSchemaForm/JsonSchemaForm.demo.vue} +0 -0
  83. /package/src/forms/{JsonSchemaForm.md → JsonSchemaForm/JsonSchemaForm.md} +0 -0
  84. /package/src/forms/{JsonSchemaForm.property.test.ts → JsonSchemaForm/JsonSchemaForm.property.test.ts} +0 -0
  85. /package/src/forms/{JsonSchemaForm.test.ts → JsonSchemaForm/JsonSchemaForm.test.ts} +0 -0
  86. /package/src/forms/{JsonSchemaForm.unit.test.ts → JsonSchemaForm/JsonSchemaForm.unit.test.ts} +0 -0
  87. /package/src/forms/{JsonSchemaForm.vue → JsonSchemaForm/JsonSchemaForm.vue} +0 -0
  88. /package/src/navigation/{Breadcrumbs.demo.vue → Breadcrumbs/Breadcrumbs.demo.vue} +0 -0
  89. /package/src/navigation/{Breadcrumbs.md → Breadcrumbs/Breadcrumbs.md} +0 -0
  90. /package/src/navigation/{Breadcrumbs.test.ts → Breadcrumbs/Breadcrumbs.test.ts} +0 -0
  91. /package/src/navigation/{Breadcrumbs.vue → Breadcrumbs/Breadcrumbs.vue} +0 -0
  92. /package/src/navigation/{Stepper.demo.vue → Stepper/Stepper.demo.vue} +0 -0
  93. /package/src/navigation/{Stepper.md → Stepper/Stepper.md} +0 -0
  94. /package/src/navigation/{Stepper.vue → Stepper/Stepper.vue} +0 -0
  95. /package/src/navigation/{Tabs.demo.vue → Tabs/Tabs.demo.vue} +0 -0
  96. /package/src/navigation/{Tabs.md → Tabs/Tabs.md} +0 -0
  97. /package/src/navigation/{Tabs.test.ts → Tabs/Tabs.test.ts} +0 -0
  98. /package/src/navigation/{Tabs.vue → Tabs/Tabs.vue} +0 -0
  99. /package/src/overlays/{Alert.demo.vue → Alert/Alert.demo.vue} +0 -0
  100. /package/src/overlays/{Alert.md → Alert/Alert.md} +0 -0
  101. /package/src/overlays/{Alert.test.ts → Alert/Alert.test.ts} +0 -0
  102. /package/src/overlays/{Alert.vue → Alert/Alert.vue} +0 -0
  103. /package/src/overlays/{Drawer.md → Drawer/Drawer.md} +0 -0
  104. /package/src/overlays/{Drawer.test.ts → Drawer/Drawer.test.ts} +0 -0
  105. /package/src/overlays/{Drawer.vue → Drawer/Drawer.vue} +0 -0
  106. /package/src/overlays/{Modal.demo.vue → Modal/Modal.demo.vue} +0 -0
  107. /package/src/overlays/{Modal.md → Modal/Modal.md} +0 -0
  108. /package/src/overlays/{Modal.test.ts → Modal/Modal.test.ts} +0 -0
  109. /package/src/overlays/{Modal.vue → Modal/Modal.vue} +0 -0
  110. /package/src/overlays/{Notification.md → Notification/Notification.md} +0 -0
  111. /package/src/overlays/{Notification.test.ts → Notification/Notification.test.ts} +0 -0
  112. /package/src/overlays/{Notification.vue → Notification/Notification.vue} +0 -0
@@ -88,7 +88,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
88
88
  };
89
89
  }
90
90
  });
91
- const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-c776bc53"]]);
91
+ const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-ece16231"]]);
92
92
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
93
93
  __name: "Stepper",
94
94
  props: {
@@ -226,7 +226,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
226
226
  };
227
227
  }
228
228
  });
229
- const Breadcrumbs = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-3137d38d"]]);
229
+ const Breadcrumbs = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-4a163049"]]);
230
230
  const _sfc_main = /* @__PURE__ */ defineComponent({
231
231
  __name: "AdminWrapper",
232
232
  props: {
@@ -238,6 +238,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
238
238
  selectItems: { default: () => [] },
239
239
  selectedItem: { default: () => ({ name: "", id: "" }) },
240
240
  productsSidebar: { default: () => [] },
241
+ profileMenuItems: { default: () => [] },
241
242
  sidebarOpenByDefault: { type: Boolean, default: true }
242
243
  },
243
244
  emits: ["selectChanged"],
@@ -246,29 +247,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
246
247
  const emit = __emit;
247
248
  const sidebarOpen = ref(props.sidebarOpenByDefault);
248
249
  const user = useStore($user);
250
+ const defaultProfileMenu = [
251
+ { name: "Profile", id: "profile", href: "/admin/user" },
252
+ { name: "Settings", id: "settings", href: "/admin/settings" },
253
+ { name: "Logout", id: "logout", href: "#" }
254
+ ];
249
255
  const topbarConfig = computed(() => {
250
256
  var _a, _b, _c;
251
257
  return {
252
258
  logo: props.sidebarLogo,
253
259
  accountLogo: ((_a = user.value) == null ? void 0 : _a.avatar) || "",
254
260
  alerted: false,
255
- profileMenu: [
256
- {
257
- name: "Profile",
258
- id: "profile",
259
- href: "/profile"
260
- },
261
- {
262
- name: "Settings",
263
- id: "settings",
264
- href: "/settings"
265
- },
266
- {
267
- name: "Logout",
268
- id: "logout",
269
- href: "#"
270
- }
271
- ],
261
+ profileMenu: props.profileMenuItems.length > 0 ? props.profileMenuItems : defaultProfileMenu,
272
262
  brand: {
273
263
  name: ((_b = user.value) == null ? void 0 : _b.username) || "User",
274
264
  description: ((_c = user.value) == null ? void 0 : _c.email) || ""
@@ -297,20 +287,27 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
297
287
  }
298
288
  };
299
289
  const handleTopBarClick = (event) => {
300
- let menuItem;
290
+ let menuItemId;
291
+ let menuItemHref;
301
292
  if (typeof event === "string") {
302
- menuItem = event;
293
+ menuItemId = event;
303
294
  } else if (event && typeof event === "object") {
304
295
  const eventObj = event;
305
- menuItem = eventObj.name || eventObj.href;
296
+ menuItemId = eventObj.id || eventObj.name;
297
+ menuItemHref = eventObj.href;
306
298
  }
307
- console.log("Extracted menu item:", menuItem);
308
- if (menuItem === "logout") {
299
+ if (menuItemId === "logout") {
309
300
  handleLogout();
310
- } else if (menuItem === "profile") {
311
- window.location.href = "/profile";
312
- } else if (menuItem === "settings") {
313
- window.location.href = "/settings";
301
+ return;
302
+ }
303
+ if (menuItemHref && menuItemHref !== "#") {
304
+ window.location.href = menuItemHref;
305
+ return;
306
+ }
307
+ const profileMenu = topbarConfig.value.profileMenu;
308
+ const menuItem = profileMenu.find((item) => item.id === menuItemId || item.name === menuItemId);
309
+ if ((menuItem == null ? void 0 : menuItem.href) && menuItem.href !== "#") {
310
+ window.location.href = menuItem.href;
314
311
  }
315
312
  };
316
313
  const handleSideBarClick = (itemId) => {
@@ -364,4 +361,4 @@ export {
364
361
  _sfc_main$2 as _,
365
362
  _sfc_main as a
366
363
  };
367
- //# sourceMappingURL=AdminWrapper.vue_vue_type_script_setup_true_lang-B32IylcT.js.map
364
+ //# sourceMappingURL=AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminWrapper.vue_vue_type_script_setup_true_lang-BhnWQ-b0.js","sources":["../src/navigation/Tabs/Tabs.vue","../src/navigation/Stepper/Stepper.vue","../src/navigation/Breadcrumbs/Breadcrumbs.vue","../src/navigation/AdminWrapper/AdminWrapper.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nexport interface Tab {\n id: string;\n label: string;\n count?: number;\n}\n\ninterface Props {\n tabs: Tab[];\n modelValue?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: ''\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [tabId: string];\n 'tab-change': [tabId: string];\n}>();\n\n// Internal state synced with v-model\nconst currentTab = computed({\n get: () => props.modelValue || (props.tabs.length > 0 ? props.tabs[0].id : ''),\n set: (value: string) => {\n emit('update:modelValue', value);\n emit('tab-change', value);\n }\n});\n\n\n\n// Expose methods for parent components\ndefineExpose({\n setActiveTab: (tabId: string) => { currentTab.value = tabId; },\n getActiveTab: () => currentTab.value,\n nextTab: () => {\n const currentIndex = props.tabs.findIndex(t => t.id === currentTab.value);\n if (currentIndex < props.tabs.length - 1) {\n currentTab.value = props.tabs[currentIndex + 1].id;\n }\n },\n previousTab: () => {\n const currentIndex = props.tabs.findIndex(t => t.id === currentTab.value);\n if (currentIndex > 0) {\n currentTab.value = props.tabs[currentIndex - 1].id;\n }\n }\n});\n</script>\n\n<template>\n <div class=\"tabs-wrapper\">\n <div class=\"border-b border-gray-200\">\n <nav class=\"-mb-px flex space-x-8\" aria-label=\"Tabs\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n @click=\"currentTab = tab.id\"\n :class=\"[\n currentTab === tab.id\n ? 'border-blue-500 text-blue-600'\n : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700',\n 'whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-colors'\n ]\"\n :aria-current=\"currentTab === tab.id ? 'page' : undefined\"\n >\n {{ tab.label }}\n <span\n v-if=\"tab.count !== undefined && tab.count > 0\"\n :class=\"[\n currentTab === tab.id\n ? 'bg-blue-100 text-blue-600'\n : 'bg-gray-100 text-gray-900',\n 'ml-3 hidden rounded-full py-0.5 px-2.5 text-xs font-medium md:inline-block'\n ]\"\n >\n {{ tab.count }}\n </span>\n </button>\n </nav>\n </div>\n \n <div class=\"tabs-content mt-4\">\n <template v-for=\"tab in tabs\" :key=\"tab.id\">\n <div v-if=\"currentTab === tab.id\">\n <slot :name=\"tab.id\" :active-tab=\"currentTab\" />\n </div>\n </template>\n </div>\n </div>\n</template>\n\n<style scoped>\n.tabs-wrapper {\n width: 100%;\n}\n\n.tabs-content {\n margin-top: 1rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiStepsV4 } from '@hotelinking/ui';\n\nexport interface Step {\n id?: string | number;\n label: string;\n status?: 'complete' | 'current' | 'upcoming';\n valid?: boolean; // Validation state for the step\n}\n\ninterface Props {\n steps: Step[];\n currentStep?: number;\n validateOnNext?: boolean; // Enable validation when moving forward\n allowSkip?: boolean; // Allow skipping to any step regardless of validation\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n currentStep: 0,\n validateOnNext: false,\n allowSkip: false\n});\n\nconst emit = defineEmits<{\n 'step-click': [step: Step, index: number];\n 'step-completed': [step: Step];\n 'step-current': [step: Step];\n 'step-upcoming': [step: Step];\n 'validation-failed': [step: Step, index: number];\n 'update:currentStep': [index: number]; // v-model support\n}>();\n\n// Transform steps to uiStepsV4 format\nconst uiSteps = computed(() =>\n props.steps.map((step, index) => ({\n id: step.id || String(index + 1).padStart(2, '0'),\n name: step.label,\n status: step.status || (\n index < props.currentStep ? 'complete' :\n index === props.currentStep ? 'current' :\n 'upcoming'\n )\n }))\n);\n\n// Check if navigation to a step is allowed\nfunction canNavigateToStep(targetIndex: number): boolean {\n if (props.allowSkip) return true;\n if (!props.validateOnNext) return true;\n if (targetIndex < props.currentStep) return true;\n\n const currentStepData = props.steps[props.currentStep];\n if (targetIndex > props.currentStep && currentStepData.valid === false) {\n return false;\n }\n\n for (let i = props.currentStep; i < targetIndex; i++) {\n if (props.steps[i].valid === false) {\n return false;\n }\n }\n\n return true;\n}\n\n// Handle uiStepsV4 events\nfunction handleStepClick(step: any, index: number) {\n const originalStep = props.steps[index];\n \n if (!canNavigateToStep(index)) {\n const currentStepData = props.steps[props.currentStep];\n emit('validation-failed', currentStepData, props.currentStep);\n return;\n }\n\n emit('step-click', originalStep, index);\n emit('update:currentStep', index);\n}\n\nfunction handleStepCompleted(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-completed', props.steps[index]);\n }\n}\n\nfunction handleStepCurrent(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-current', props.steps[index]);\n }\n}\n\nfunction handleStepUpcoming(step: any) {\n const index = uiSteps.value.findIndex(s => s.id === step.id);\n if (index !== -1) {\n emit('step-upcoming', props.steps[index]);\n }\n}\n\n// Public methods for programmatic navigation\nfunction goToStep(index: number): boolean {\n if (index < 0 || index >= props.steps.length) return false;\n if (!canNavigateToStep(index)) {\n const currentStepData = props.steps[props.currentStep];\n emit('validation-failed', currentStepData, props.currentStep);\n return false;\n }\n emit('update:currentStep', index);\n return true;\n}\n\nfunction goToNext(): boolean {\n return goToStep(props.currentStep + 1);\n}\n\nfunction goToPrevious(): boolean {\n return goToStep(props.currentStep - 1);\n}\n\nfunction validateCurrentStep(): boolean {\n const currentStepData = props.steps[props.currentStep];\n return currentStepData.valid !== false;\n}\n\ndefineExpose({\n getCurrentStep: () => props.currentStep,\n getSteps: () => props.steps,\n goToStep,\n goToNext,\n goToPrevious,\n validateCurrentStep,\n canNavigateToStep\n});\n</script>\n\n<template>\n <uiStepsV4\n :steps=\"uiSteps\"\n @stepClick=\"handleStepClick\"\n @stepCompleted=\"handleStepCompleted\"\n @stepCurrent=\"handleStepCurrent\"\n @stepUpcoming=\"handleStepUpcoming\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiBreadcrumbs } from '@hotelinking/ui';\n\nexport interface BreadcrumbItem {\n label: string;\n routeName: string;\n current?: boolean;\n}\n\ninterface Props {\n items: BreadcrumbItem[];\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n loading: false\n});\n\nconst emit = defineEmits<{\n 'breadcrumb-click': [routeName: string];\n}>();\n\n// Convert items to uiBreadcrumbs format\nconst pagesConfig = computed(() =>\n props.items.map((item, index) => ({\n name: item.label,\n routeName: item.routeName,\n current: item.current ?? (index === props.items.length - 1)\n }))\n);\n\n// Handle breadcrumb click\nfunction handleBreadcrumbClick(routeName: string) {\n emit('breadcrumb-click', routeName);\n}\n\n// Expose methods for parent components\ndefineExpose({\n getItems: () => props.items\n});\n</script>\n\n<template>\n <div class=\"breadcrumbs-wrapper\">\n <uiBreadcrumbs\n :pages=\"pagesConfig\"\n :loading=\"loading\"\n @bread-crumb-clicked=\"handleBreadcrumbClick\"\n />\n </div>\n</template>\n\n<style scoped>\n.breadcrumbs-wrapper {\n width: 100%;\n}\n</style>\n","/**\n * Admin Wrapper Component\n * \n * Wraps uiWrapper from @hotelinking/ui with sidebar, topbar, and content area.\n */\n\n<template>\n <uiWrapper \n :sidebar=\"sidebarConfig as any\" \n :topbar=\"topbarConfig as any\"\n :sidebarOpen=\"sidebarOpen\"\n @selectChanged=\"handleSelectChanged\"\n @topBarClick=\"handleTopBarClick\"\n @sideBarClick=\"handleSideBarClick\"\n @productBarClick=\"handleProductBarClick\"\n @inputChanged=\"handleInputChanged\"\n @sidebarToggle=\"(isOpen: boolean) => sidebarOpen = isOpen\"\n >\n <slot></slot>\n </uiWrapper>\n</template>\n\n<script setup lang=\"ts\">\nimport type { SelectItemType } from \"@hotelinking/ui\";\nimport { uiWrapper } from \"@hotelinking/ui\";\nimport { useStore } from \"@nanostores/vue\";\nimport { computed, ref } from \"vue\";\nimport { $user } from \"../../stores/user\";\n\n// Profile menu item interface\ninterface ProfileMenuItem {\n\tname: string;\n\tid: string;\n\thref: string;\n}\n\n// Props interface (user is now from nanostore)\ninterface Props {\n\tsidebarLogo: string;\n\tcurrentPage?: string;\n\tsidebarTitle?: string;\n\tsidebarItems?: Array<{\n\t\tname: string;\n\t\ticon?: string;\n\t\tid: string;\n\t\trouteName: string;\n\t}>;\n\ttopbarActions?: Array<{\n\t\tname: string;\n\t\tevent: string;\n\t\ticon: string;\n\t}>;\n\tselectItems?: Array<{\n\t\tname: string;\n\t\tid: string;\n\t}>;\n\tselectedItem?: {\n\t\tname: string;\n\t\tid: string;\n\t};\n\tproductsSidebar?: Array<{\n\t\tname: string;\n\t\ticon: string;\n\t\tactive?: boolean;\n\t}>;\n\tprofileMenuItems?: ProfileMenuItem[];\n\tsidebarOpenByDefault?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n\tcurrentPage: \"dashboard\",\n\tsidebarItems: () => [],\n\ttopbarActions: () => [],\n\tselectItems: () => [],\n\tselectedItem: () => ({ name: \"\", id: \"\" }),\n\tproductsSidebar: () => [],\n\tprofileMenuItems: () => [],\n\tsidebarOpenByDefault: true,\n});\n\n// Emit events\nconst emit = defineEmits<{\n\tselectChanged: [item: { name: string; id: string }];\n}>();\n\n// Reactive state\nconst sidebarOpen = ref(props.sidebarOpenByDefault);\n\n// Get user from nanostore (no props needed!)\nconst user = useStore($user);\n\n// Default profile menu items (used when none provided via props)\nconst defaultProfileMenu: ProfileMenuItem[] = [\n\t{ name: \"Profile\", id: \"profile\", href: \"/admin/user\" },\n\t{ name: \"Settings\", id: \"settings\", href: \"/admin/settings\" },\n\t{ name: \"Logout\", id: \"logout\", href: \"#\" },\n];\n\n// Computed properties for UI configuration\nconst topbarConfig = computed(() => {\n\treturn {\n\t\tlogo: props.sidebarLogo,\n\t\taccountLogo: user.value?.avatar || \"\",\n\t\talerted: false,\n\t\tprofileMenu: props.profileMenuItems.length > 0\n\t\t\t? props.profileMenuItems\n\t\t\t: defaultProfileMenu,\n\t\tbrand: {\n\t\t\tname: user.value?.username || \"User\",\n\t\t\tdescription: user.value?.email || \"\",\n\t\t},\n\t\tselectItems: props.selectItems,\n\t\tselectedItem: props.selectedItem,\n\t};\n});\n\nconst sidebarConfig = computed(() => {\n\t// Add current attribute dynamically based on currentPage\n\tconst navigationItems = props.sidebarItems.map((item) => ({\n\t\tname: item.name,\n\t\ticon: item.icon,\n\t\tid: item.id,\n\t\tcurrent: item.id === props.currentPage,\n\t}));\n\n\treturn {\n\t\tnavigation: navigationItems,\n\t\tproductsSidebar: props.productsSidebar,\n\t\tlogo: props.sidebarLogo,\n\t};\n});\n\n// Event handlers\nconst handleSelectChanged = (item: SelectItemType | SelectItemType[]) => {\n\tconsole.log(\"Select changed:\", item);\n\t// Emit to parent component\n\tif (!Array.isArray(item) && item.id) {\n\t\temit(\"selectChanged\", { name: item.name, id: item.id });\n\t}\n};\n\nconst handleTopBarClick = (event: unknown) => {\n\t// Handle different possible event formats\n\tlet menuItemId: string | undefined;\n\tlet menuItemHref: string | undefined;\n\n\tif (typeof event === \"string\") {\n\t\tmenuItemId = event;\n\t} else if (event && typeof event === \"object\") {\n\t\tconst eventObj = event as Record<string, unknown>;\n\t\tmenuItemId = (eventObj.id as string) || (eventObj.name as string);\n\t\tmenuItemHref = eventObj.href as string;\n\t}\n\n\t// Handle logout separately\n\tif (menuItemId === \"logout\") {\n\t\thandleLogout();\n\t\treturn;\n\t}\n\n\t// Navigate using href from the event object or find it from profile menu\n\tif (menuItemHref && menuItemHref !== \"#\") {\n\t\twindow.location.href = menuItemHref;\n\t\treturn;\n\t}\n\n\t// Fallback: find the menu item by id and use its href\n\tconst profileMenu = topbarConfig.value.profileMenu;\n\tconst menuItem = profileMenu.find((item) => item.id === menuItemId || item.name === menuItemId);\n\tif (menuItem?.href && menuItem.href !== \"#\") {\n\t\twindow.location.href = menuItem.href;\n\t}\n};\n\nconst handleSideBarClick = (itemId: string) => {\n\tconsole.log(\"Sidebar click:\", itemId);\n\n\t// Find the item by id to get the routeName\n\tconst item = props.sidebarItems.find(\n\t\t(i) => (i.id || i.name.toLowerCase()) === itemId,\n\t);\n\n\tif (item?.routeName) {\n\t\twindow.location.href = item.routeName;\n\t}\n};\n\nconst handleProductBarClick = (event: unknown) => {\n\tconsole.log(\"Product bar click:\", event);\n};\n\nconst handleInputChanged = (event: unknown) => {\n\tconsole.log(\"Input changed:\", event);\n};\n\nconst handleLogout = async () => {\n\ttry {\n\t\t// Import logout from auth package\n\t\tconst { signOut } = await import('@htlkg/core/auth');\n\t\tawait signOut();\n\t\t// Redirect to login page\n\t\twindow.location.href = \"/login\";\n\t} catch (error) {\n\t\tconsole.error(\"Logout error:\", error);\n\t\t// Force redirect even if logout fails\n\t\twindow.location.href = \"/login\";\n\t}\n};\n</script>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_Fragment","_renderList","_normalizeClass","_toDisplayString","_renderSlot","_createBlock","_unref","_createVNode"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js","sources":["../src/overlays/Modal.vue","../src/overlays/Drawer.vue","../src/overlays/Notification.vue","../src/overlays/Alert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiModal as UiModal, type UiModalInterface } from '@hotelinking/ui';\n\ninterface Props {\n open?: boolean;\n title?: string;\n content?: string;\n modalName?: string;\n actions?: UiModalInterface['actions'];\n size?: 'small' | 'medium' | 'large';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n title: '',\n content: '',\n modalName: 'modal',\n actions: () => [],\n size: 'medium'\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n 'action': [action: any];\n}>();\n\n// Internal state synced with v-model\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiModal format\nconst modalConfig = computed<UiModalInterface>(() => ({\n title: props.title,\n content: props.content,\n modalName: props.modalName,\n open: isOpen.value,\n actions: props.actions\n}));\n\n// Handle modal actions from uiModal\n// uiModal emits: { modal: string, action: string }\nfunction handleModalAction(data: { modal: string; action: string }) {\n emit('action', data);\n \n // Close modal when clicking X, clicking outside, or any action\n // This matches uiModal behavior where any action closes the modal\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <UiModal\n :title=\"modalConfig.title\"\n :content=\"modalConfig.content\"\n :modalName=\"modalConfig.modalName\"\n :open=\"modalConfig.open\"\n :actions=\"modalConfig.actions\"\n @modalAction=\"handleModalAction\"\n >\n <template v-if=\"$slots.default\" #default>\n <slot />\n </template>\n <template v-if=\"$slots.header\" #header>\n <slot name=\"header\" />\n </template>\n <template v-if=\"$slots.footer\" #footer>\n <slot name=\"footer\" />\n </template>\n </UiModal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n open?: boolean;\n position?: 'left' | 'right' | 'top' | 'bottom';\n title?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n position: 'right',\n title: ''\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n}>();\n\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) emit('close');\n }\n});\n\nfunction close() {\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <!-- Overlay -->\n <div\n v-if=\"isOpen\"\n class=\"fixed inset-0 bg-black bg-opacity-50 z-50\"\n @click=\"close\"\n >\n <!-- Drawer -->\n <div\n class=\"fixed bg-white shadow-xl z-51\"\n :class=\"{\n 'top-0 right-0 bottom-0 w-96 max-w-[90vw]': position === 'right',\n 'top-0 left-0 bottom-0 w-96 max-w-[90vw]': position === 'left',\n 'top-0 left-0 right-0 h-96 max-h-[90vh]': position === 'top',\n 'bottom-0 left-0 right-0 h-96 max-h-[90vh]': position === 'bottom'\n }\"\n @click.stop\n >\n <!-- Header -->\n <div class=\"flex justify-between items-center p-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium\">{{ title }}</h3>\n <button\n @click=\"close\"\n class=\"text-2xl text-gray-500 hover:text-gray-700 bg-transparent border-none cursor-pointer\"\n >\n ×\n </button>\n </div>\n \n <!-- Content -->\n <div class=\"p-4 overflow-auto\">\n <slot />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiNotification } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n message?: string;\n type?: 'info' | 'success' | 'warning' | 'danger';\n show?: boolean;\n fixed?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n message: '',\n type: 'info',\n show: false,\n fixed: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Handle notification close\nfunction handleClose() {\n isVisible.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <uiNotification\n :show=\"isVisible\"\n :type=\"type\"\n :title=\"title\"\n :message=\"message\"\n :fixed=\"fixed\"\n @close-notification=\"handleClose\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiAlert, type UiAlertInterface } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n type?: UiAlertInterface['type'];\n actions?: UiAlertInterface['actions'];\n loading?: boolean;\n show?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'info',\n actions: () => [],\n loading: false,\n show: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'alertEvent': [event: string];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiAlert format\nconst alertConfig = computed<UiAlertInterface>(() => ({\n title: props.title,\n type: props.type,\n actions: props.actions,\n loading: props.loading\n}));\n\n// Handle alert action events from uiAlert\nfunction handleAlertEvent(event: string) {\n emit('alertEvent', event);\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <div v-if=\"isVisible\">\n <uiAlert\n :title=\"alertConfig.title\"\n :type=\"alertConfig.type\"\n :actions=\"alertConfig.actions\"\n :loading=\"alertConfig.loading\"\n @alert-event=\"handleAlertEvent\"\n >\n <slot />\n </uiAlert>\n </div>\n</template>\n"],"names":["_createBlock","_unref","UiModal","$slots","_renderSlot","_createElementBlock","_createElementVNode","_hoisted_1","_toDisplayString","_createVNode"],"mappings":"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"}
1
+ {"version":3,"file":"Alert.vue_vue_type_script_setup_true_lang-DxPCS-Hx.js","sources":["../src/overlays/Modal/Modal.vue","../src/overlays/Drawer/Drawer.vue","../src/overlays/Notification/Notification.vue","../src/overlays/Alert/Alert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiModal as UiModal, type UiModalInterface } from '@hotelinking/ui';\n\ninterface Props {\n open?: boolean;\n title?: string;\n content?: string;\n modalName?: string;\n actions?: UiModalInterface['actions'];\n size?: 'small' | 'medium' | 'large';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n title: '',\n content: '',\n modalName: 'modal',\n actions: () => [],\n size: 'medium'\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n 'action': [action: any];\n}>();\n\n// Internal state synced with v-model\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiModal format\nconst modalConfig = computed<UiModalInterface>(() => ({\n title: props.title,\n content: props.content,\n modalName: props.modalName,\n open: isOpen.value,\n actions: props.actions\n}));\n\n// Handle modal actions from uiModal\n// uiModal emits: { modal: string, action: string }\nfunction handleModalAction(data: { modal: string; action: string }) {\n emit('action', data);\n \n // Close modal when clicking X, clicking outside, or any action\n // This matches uiModal behavior where any action closes the modal\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <UiModal\n :title=\"modalConfig.title\"\n :content=\"modalConfig.content\"\n :modalName=\"modalConfig.modalName\"\n :open=\"modalConfig.open\"\n :actions=\"modalConfig.actions\"\n @modalAction=\"handleModalAction\"\n >\n <template v-if=\"$slots.default\" #default>\n <slot />\n </template>\n <template v-if=\"$slots.header\" #header>\n <slot name=\"header\" />\n </template>\n <template v-if=\"$slots.footer\" #footer>\n <slot name=\"footer\" />\n </template>\n </UiModal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface Props {\n open?: boolean;\n position?: 'left' | 'right' | 'top' | 'bottom';\n title?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n open: false,\n position: 'right',\n title: ''\n});\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'close': [];\n}>();\n\nconst isOpen = computed({\n get: () => props.open,\n set: (value: boolean) => {\n emit('update:open', value);\n if (!value) emit('close');\n }\n});\n\nfunction close() {\n isOpen.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n open: () => { isOpen.value = true; },\n close: () => { isOpen.value = false; },\n toggle: () => { isOpen.value = !isOpen.value; }\n});\n</script>\n\n<template>\n <!-- Overlay -->\n <div\n v-if=\"isOpen\"\n class=\"fixed inset-0 bg-black bg-opacity-50 z-50\"\n @click=\"close\"\n >\n <!-- Drawer -->\n <div\n class=\"fixed bg-white shadow-xl z-51\"\n :class=\"{\n 'top-0 right-0 bottom-0 w-96 max-w-[90vw]': position === 'right',\n 'top-0 left-0 bottom-0 w-96 max-w-[90vw]': position === 'left',\n 'top-0 left-0 right-0 h-96 max-h-[90vh]': position === 'top',\n 'bottom-0 left-0 right-0 h-96 max-h-[90vh]': position === 'bottom'\n }\"\n @click.stop\n >\n <!-- Header -->\n <div class=\"flex justify-between items-center p-4 border-b border-gray-200\">\n <h3 class=\"text-lg font-medium\">{{ title }}</h3>\n <button\n @click=\"close\"\n class=\"text-2xl text-gray-500 hover:text-gray-700 bg-transparent border-none cursor-pointer\"\n >\n ×\n </button>\n </div>\n \n <!-- Content -->\n <div class=\"p-4 overflow-auto\">\n <slot />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiNotification } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n message?: string;\n type?: 'info' | 'success' | 'warning' | 'danger';\n show?: boolean;\n fixed?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n message: '',\n type: 'info',\n show: false,\n fixed: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Handle notification close\nfunction handleClose() {\n isVisible.value = false;\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <uiNotification\n :show=\"isVisible\"\n :type=\"type\"\n :title=\"title\"\n :message=\"message\"\n :fixed=\"fixed\"\n @close-notification=\"handleClose\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiAlert, type UiAlertInterface } from '@hotelinking/ui';\n\ninterface Props {\n title: string;\n type?: UiAlertInterface['type'];\n actions?: UiAlertInterface['actions'];\n loading?: boolean;\n show?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n type: 'info',\n actions: () => [],\n loading: false,\n show: true\n});\n\nconst emit = defineEmits<{\n 'update:show': [value: boolean];\n 'alertEvent': [event: string];\n 'close': [];\n}>();\n\n// Internal state synced with v-model\nconst isVisible = computed({\n get: () => props.show,\n set: (value: boolean) => {\n emit('update:show', value);\n if (!value) {\n emit('close');\n }\n }\n});\n\n// Convert to uiAlert format\nconst alertConfig = computed<UiAlertInterface>(() => ({\n title: props.title,\n type: props.type,\n actions: props.actions,\n loading: props.loading\n}));\n\n// Handle alert action events from uiAlert\nfunction handleAlertEvent(event: string) {\n emit('alertEvent', event);\n}\n\n// Expose methods for parent components\ndefineExpose({\n show: () => { isVisible.value = true; },\n hide: () => { isVisible.value = false; },\n toggle: () => { isVisible.value = !isVisible.value; }\n});\n</script>\n\n<template>\n <div v-if=\"isVisible\">\n <uiAlert\n :title=\"alertConfig.title\"\n :type=\"alertConfig.type\"\n :actions=\"alertConfig.actions\"\n :loading=\"alertConfig.loading\"\n @alert-event=\"handleAlertEvent\"\n >\n <slot />\n </uiAlert>\n </div>\n</template>\n"],"names":["_createBlock","_unref","UiModal","$slots","_renderSlot","_createElementBlock","_createElementVNode","_hoisted_1","_toDisplayString","_createVNode"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js","sources":["../src/forms/JsonSchemaForm.vue","../src/forms/DateRange.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport _Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport {\n uiInput,\n uiSelect,\n uiToggle,\n uiRangeSlider,\n uiTextArea,\n uiButton\n} from '@hotelinking/ui';\n\n// Handle ESM/CJS interop for ajv\nconst Ajv = (_Ajv as unknown as { default: typeof _Ajv }).default ?? _Ajv;\n\n// Initialize AJV for JSON Schema validation with format support\nconst ajv = new Ajv({ allErrors: true });\naddFormats(ajv); // Add support for format keywords like \"email\", \"uri\", \"date\", etc.\n\ninterface JsonSchema {\n type: string;\n properties?: Record<string, any>;\n required?: string[];\n title?: string;\n description?: string;\n}\n\ninterface Props {\n schema: JsonSchema;\n modelValue?: Record<string, any>;\n uiSchema?: Record<string, any>;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: () => ({}),\n uiSchema: () => ({}),\n loading: false\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: Record<string, any>];\n 'validation-error': [errors: Array<{ field: string; message: string }>];\n 'submit': [value: Record<string, any>];\n}>();\n\n// Internal form data\nconst formData = computed({\n get: () => props.modelValue,\n set: (value: Record<string, any>) => {\n emit('update:modelValue', value);\n }\n});\n\nconst errors = ref<Record<string, string>>({});\nconst touched = ref<Record<string, boolean>>({});\n\n// Get widget type from UI schema or infer from field schema\nfunction getWidget(fieldName: string): string {\n const uiSchemaField = props.uiSchema[fieldName];\n if (uiSchemaField?.['ui:widget']) {\n return uiSchemaField['ui:widget'];\n }\n \n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema) return 'text';\n \n // Infer widget from schema\n if (fieldSchema.type === 'boolean') return 'toggle';\n if (fieldSchema.type === 'number' || fieldSchema.type === 'integer') {\n // Only use slider if explicitly specified in uiSchema\n // Don't auto-infer from min/max presence\n return 'number';\n }\n if (fieldSchema.type === 'string') {\n if (fieldSchema.enum) return 'select';\n if (fieldSchema.format === 'email') return 'email';\n if (fieldSchema.format === 'uri') return 'url';\n if (fieldSchema.minLength && fieldSchema.minLength > 100) return 'textarea';\n }\n if (fieldSchema.type === 'array') return 'array';\n if (fieldSchema.type === 'object') return 'object';\n \n return 'text';\n}\n\n// Get input type for uiInput component\nfunction getInputType(fieldName: string): 'text' | 'email' | 'password' | 'number' | 'date' | 'datetime-local' {\n const widget = getWidget(fieldName);\n \n if (widget === 'password') return 'password';\n if (widget === 'email') return 'email';\n if (widget === 'number') return 'number';\n if (widget === 'date') return 'date';\n if (widget === 'datetime-local') return 'datetime-local';\n \n return 'text';\n}\n\n// Get field color based on validation state (computed for reactivity)\nfunction getFieldColor(fieldName: string): 'gray' | 'green' | 'red' | 'yellow' {\n // Check for errors first (most important)\n if (errors.value[fieldName]) return 'red';\n \n // If field has been touched and has a valid value, show green\n if (touched.value[fieldName]) {\n const value = formData.value[fieldName];\n if (isRequired(fieldName) && value !== undefined && value !== null && value !== '') {\n return 'green';\n }\n }\n \n // Default to gray\n return 'gray';\n}\n\n// Check if field is required\nfunction isRequired(fieldName: string): boolean {\n return props.schema.required?.includes(fieldName) ?? false;\n}\n\n// Get field label\nfunction getFieldLabel(fieldName: string): string {\n const fieldSchema = props.schema.properties?.[fieldName];\n return fieldSchema?.title || fieldName;\n}\n\n// Get field description\nfunction getFieldDescription(fieldName: string): string {\n const fieldSchema = props.schema.properties?.[fieldName];\n return fieldSchema?.description || '';\n}\n\n// Get placeholder from UI schema\nfunction getPlaceholder(fieldName: string): string {\n return props.uiSchema[fieldName]?.['ui:placeholder'] || '';\n}\n\n// Get autocomplete attribute for better UX (especially for passwords)\n// Following https://www.chromium.org/developers/design-documents/create-amazing-password-forms/\nfunction getAutocomplete(fieldName: string): string | undefined {\n const widget = getWidget(fieldName);\n const fieldSchema = props.schema.properties?.[fieldName];\n \n // Check if explicitly set in uiSchema\n if (props.uiSchema[fieldName]?.['ui:autocomplete']) {\n return props.uiSchema[fieldName]['ui:autocomplete'];\n }\n \n // Auto-detect based on field name and type\n const lowerFieldName = fieldName.toLowerCase();\n \n if (widget === 'email' || fieldSchema?.format === 'email') {\n return 'email';\n }\n \n if (widget === 'password') {\n // Check for common password field patterns\n if (lowerFieldName.includes('new') || lowerFieldName.includes('confirm')) {\n return 'new-password';\n }\n if (lowerFieldName.includes('current') || lowerFieldName === 'password') {\n return 'current-password';\n }\n return 'current-password'; // Default for password fields\n }\n \n // Common autocomplete values\n if (lowerFieldName.includes('username') || lowerFieldName === 'user') {\n return 'username';\n }\n if (lowerFieldName.includes('name')) {\n if (lowerFieldName.includes('first')) return 'given-name';\n if (lowerFieldName.includes('last')) return 'family-name';\n return 'name';\n }\n if (lowerFieldName.includes('phone') || lowerFieldName.includes('tel')) {\n return 'tel';\n }\n if (lowerFieldName.includes('address')) {\n return 'street-address';\n }\n if (lowerFieldName.includes('city')) {\n return 'address-level2';\n }\n if (lowerFieldName.includes('country')) {\n return 'country-name';\n }\n if (lowerFieldName.includes('postal') || lowerFieldName.includes('zip')) {\n return 'postal-code';\n }\n \n return undefined;\n}\n\n// Validate form data against schema using AJV\nfunction validate(): Array<{ field: string; message: string }> {\n const validationErrors: Array<{ field: string; message: string }> = [];\n errors.value = {};\n\n // Compile and validate using AJV\n const validateFn = ajv.compile(props.schema);\n const valid = validateFn(formData.value);\n\n if (!valid && validateFn.errors) {\n for (const error of validateFn.errors) {\n // Extract field name from instancePath (e.g., \"/fieldName\" -> \"fieldName\")\n const field = error.instancePath.replace(/^\\//, '') || error.params.missingProperty || 'form';\n \n // Generate user-friendly error message\n let message = '';\n \n if (error.keyword === 'required') {\n const missingField = error.params.missingProperty;\n message = `${getFieldLabel(missingField)} is required`;\n errors.value[missingField] = message;\n validationErrors.push({ field: missingField, message });\n } else if (error.keyword === 'type') {\n message = `${getFieldLabel(field)} must be a ${error.params.type}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'minimum') {\n message = `${getFieldLabel(field)} must be at least ${error.params.limit}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'maximum') {\n message = `${getFieldLabel(field)} must be at most ${error.params.limit}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'minLength') {\n message = `${getFieldLabel(field)} must be at least ${error.params.limit} characters`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'maxLength') {\n message = `${getFieldLabel(field)} must be at most ${error.params.limit} characters`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'format') {\n message = `${getFieldLabel(field)} must be a valid ${error.params.format}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'enum') {\n message = `${getFieldLabel(field)} must be one of: ${error.params.allowedValues.join(', ')}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else {\n // Generic error message\n message = error.message || 'Invalid value';\n errors.value[field] = message;\n validationErrors.push({ field, message });\n }\n }\n }\n\n return validationErrors;\n}\n\n// Handle form submission\nfunction handleSubmit(event: Event) {\n event.preventDefault();\n \n const validationErrors = validate();\n if (validationErrors.length > 0) {\n emit('validation-error', validationErrors);\n return;\n }\n \n emit('submit', formData.value);\n}\n\n// Update field value\nfunction updateField(field: string, value: any) {\n touched.value[field] = true;\n \n // Update formData by emitting the new value\n const newData = {\n ...formData.value,\n [field]: value\n };\n emit('update:modelValue', newData);\n \n // Validate field on change with the new value\n validateFieldWithValue(field, value);\n}\n\n// Validate a single field using AJV (reads from formData)\nfunction validateField(fieldName: string) {\n validateFieldWithValue(fieldName, formData.value[fieldName]);\n}\n\n// Validate a single field with a specific value\nfunction validateFieldWithValue(fieldName: string, fieldValue: any) {\n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema) return;\n \n // Clear existing error\n delete errors.value[fieldName];\n \n // If field is empty/null/undefined and required, show required error\n if (isRequired(fieldName) && (fieldValue === undefined || fieldValue === null || fieldValue === '')) {\n errors.value[fieldName] = `${getFieldLabel(fieldName)} is required`;\n return;\n }\n \n // If field is empty and not required, no validation needed\n if (fieldValue === undefined || fieldValue === null || fieldValue === '') {\n return;\n }\n \n // Create a mini schema for just this field (without required)\n const singleFieldSchema = {\n type: 'object',\n properties: {\n [fieldName]: fieldSchema\n }\n };\n \n // Validate just this field\n const validateFn = ajv.compile(singleFieldSchema);\n const valid = validateFn({ [fieldName]: fieldValue });\n \n if (!valid && validateFn.errors) {\n for (const error of validateFn.errors) {\n let message = '';\n \n if (error.keyword === 'type') {\n message = `${getFieldLabel(fieldName)} must be a ${error.params.type}`;\n } else if (error.keyword === 'minimum') {\n message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit}`;\n } else if (error.keyword === 'maximum') {\n message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit}`;\n } else if (error.keyword === 'minLength') {\n message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit} characters`;\n } else if (error.keyword === 'maxLength') {\n message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit} characters`;\n } else if (error.keyword === 'format') {\n message = `${getFieldLabel(fieldName)} must be a valid ${error.params.format}`;\n } else if (error.keyword === 'enum') {\n message = `${getFieldLabel(fieldName)} must be one of: ${error.params.allowedValues.join(', ')}`;\n } else {\n message = error.message || 'Invalid value';\n }\n \n errors.value[fieldName] = message;\n break; // Only show first error per field\n }\n }\n}\n\n// Get enum options for select\nfunction getSelectOptions(fieldName: string) {\n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema?.enum) return [];\n \n return fieldSchema.enum.map((value: any) => ({\n id: String(value),\n name: String(value),\n label: String(value)\n }));\n}\n\n// Get selected option for select\nfunction getSelectedOption(fieldName: string) {\n const value = formData.value[fieldName];\n if (!value) {\n // Return first option as default if available\n const options = getSelectOptions(fieldName);\n return options.length > 0 ? options[0] : { id: '', name: '', label: '' };\n }\n \n return {\n id: String(value),\n name: String(value),\n label: String(value)\n };\n}\n\n// Array field helpers\nfunction addArrayItem(fieldName: string) {\n const currentArray = formData.value[fieldName] || [];\n updateField(fieldName, [...currentArray, '']);\n}\n\nfunction removeArrayItem(fieldName: string, index: number) {\n const currentArray = formData.value[fieldName] || [];\n const newArray = currentArray.filter((_: any, i: number) => i !== index);\n updateField(fieldName, newArray);\n}\n\nfunction updateArrayItem(fieldName: string, index: number, value: any) {\n const currentArray = formData.value[fieldName] || [];\n const newArray = [...currentArray];\n newArray[index] = value;\n updateField(fieldName, newArray);\n}\n\n// Expose methods\ndefineExpose({\n validate,\n validateField,\n reset: () => { \n emit('update:modelValue', {});\n errors.value = {}; \n touched.value = {};\n },\n // Expose internal state for testing\n formData,\n errors,\n touched,\n // Expose helper methods for testing\n getFieldLabel,\n getFieldDescription,\n isRequired,\n getWidget,\n getInputType,\n getFieldColor,\n getPlaceholder,\n getSelectOptions,\n getSelectedOption,\n updateField\n});\n</script>\n\n<template>\n <form @submit=\"handleSubmit\" class=\"space-y-6\">\n <!-- Form Title and Description -->\n <div v-if=\"schema.title || schema.description\" class=\"mb-6\">\n <h2 v-if=\"schema.title\" class=\"text-2xl font-bold text-gray-900 mb-2\">\n {{ schema.title }}\n </h2>\n <p v-if=\"schema.description\" class=\"text-gray-600\">\n {{ schema.description }}\n </p>\n </div>\n\n <!-- Form Fields -->\n <div v-if=\"schema.properties\" class=\"space-y-6\">\n <div\n v-for=\"(fieldSchema, fieldName) in schema.properties\"\n :key=\"fieldName\"\n >\n <!-- Text/Email/URL/Password Input -->\n <uiInput\n v-if=\"['text', 'email', 'url', 'password'].includes(getWidget(fieldName))\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n :type=\"getInputType(fieldName)\"\n :value=\"formData[fieldName] || ''\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @input-changed=\"updateField(fieldName, $event.value)\"\n />\n\n <!-- Number Input -->\n <uiInput\n v-else-if=\"getWidget(fieldName) === 'number'\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n type=\"number\"\n :value=\"String(formData[fieldName] ?? '')\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n :min=\"schema.properties?.[fieldName]?.minimum\"\n :max=\"schema.properties?.[fieldName]?.maximum\"\n @input-changed=\"updateField(fieldName, $event.value === '' ? null : Number($event.value))\"\n />\n\n <!-- Textarea -->\n <uiTextArea\n v-else-if=\"getWidget(fieldName) === 'textarea'\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n :value=\"formData[fieldName] || ''\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n :rows=\"4\"\n @input-changed=\"updateField(fieldName, $event.value)\"\n />\n\n <!-- Select Dropdown -->\n <uiSelect\n v-else-if=\"getWidget(fieldName) === 'select'\"\n :label=\"getFieldLabel(fieldName)\"\n :items=\"getSelectOptions(fieldName)\"\n :select=\"getSelectedOption(fieldName)\"\n :placeholder=\"getPlaceholder(fieldName) || 'Select an option'\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @select-changed=\"(item: any) => updateField(fieldName, item.id)\"\n />\n\n <!-- Toggle (Boolean) -->\n <uiToggle\n v-else-if=\"getWidget(fieldName) === 'toggle'\"\n :item=\"{\n title: getFieldLabel(fieldName),\n subtitle: getFieldDescription(fieldName),\n action: fieldName\n }\"\n :checked=\"formData[fieldName]\"\n :loading=\"loading\"\n @toggle-changed=\"updateField(fieldName, $event.active)\"\n />\n\n <!-- Checkbox (Boolean alternative) -->\n <div v-else-if=\"getWidget(fieldName) === 'checkbox'\" class=\"flex items-start\">\n <input\n :id=\"fieldName\"\n type=\"checkbox\"\n :checked=\"formData[fieldName]\"\n :disabled=\"loading\"\n @change=\"updateField(fieldName, ($event.target as HTMLInputElement).checked)\"\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded mt-1\"\n />\n <label :for=\"fieldName\" class=\"ml-2 block\">\n <span class=\"text-sm font-medium text-gray-700\">\n {{ getFieldLabel(fieldName) }}\n <span v-if=\"isRequired(fieldName)\" class=\"text-red-500\">*</span>\n </span>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-500\">\n {{ getFieldDescription(fieldName) }}\n </p>\n </label>\n </div>\n\n <!-- Range Slider -->\n <uiRangeSlider\n v-else-if=\"getWidget(fieldName) === 'slider'\"\n :label=\"getFieldLabel(fieldName)\"\n :min=\"schema.properties[fieldName].minimum ?? 0\"\n :max=\"schema.properties[fieldName].maximum ?? 100\"\n :slider-value=\"formData[fieldName] ?? schema.properties[fieldName].minimum ?? 0\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @sliderUpdated=\"updateField(fieldName, $event)\"\n />\n\n <!-- Array (Simple list) -->\n <div v-else-if=\"getWidget(fieldName) === 'array'\" class=\"space-y-2\">\n <label class=\"block text-sm font-medium text-gray-700\">\n {{ getFieldLabel(fieldName) }}\n <span v-if=\"isRequired(fieldName)\" class=\"text-red-500\">*</span>\n </label>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-500 mb-2\">\n {{ getFieldDescription(fieldName) }}\n </p>\n <div v-if=\"errors[fieldName]\" class=\"text-sm text-red-600 mb-2\">\n {{ errors[fieldName] }}\n </div>\n <div class=\"space-y-2\">\n <div\n v-for=\"(item, index) in (formData[fieldName] || [])\"\n :key=\"index\"\n class=\"flex gap-2\"\n >\n <input\n type=\"text\"\n :value=\"item\"\n :disabled=\"loading\"\n @input=\"updateArrayItem(fieldName, index, ($event.target as HTMLInputElement).value)\"\n class=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <button\n type=\"button\"\n @click=\"removeArrayItem(fieldName, index)\"\n :disabled=\"loading\"\n class=\"px-3 py-2 text-red-600 hover:text-red-800 border border-red-300 rounded-md\"\n >\n Remove\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n @click=\"addArrayItem(fieldName)\"\n :disabled=\"loading\"\n class=\"mt-2 px-4 py-2 text-sm text-blue-600 hover:text-blue-800 border border-blue-300 rounded-md\"\n >\n + Add Item\n </button>\n </div>\n\n <!-- Nested Object (Simple rendering) -->\n <div v-else-if=\"getWidget(fieldName) === 'object' || getWidget(fieldName) === 'card'\" class=\"border border-gray-200 rounded-lg p-4 space-y-4\">\n <div>\n <h3 class=\"text-lg font-semibold text-gray-900 mb-1\">\n {{ getFieldLabel(fieldName) }}\n </h3>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-600 mb-4\">\n {{ getFieldDescription(fieldName) }}\n </p>\n </div>\n <div class=\"space-y-4 pl-4 border-l-2 border-gray-200\">\n <!-- Recursively render nested fields -->\n <div\n v-for=\"(subSchema, subName) in fieldSchema.properties\"\n :key=\"subName\"\n >\n <!-- Nested field rendering would go here -->\n <p class=\"text-sm text-gray-500\">\n Nested field: {{ subName }} (type: {{ subSchema.type }})\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex justify-end gap-3 pt-6 border-t\">\n <slot name=\"actions\">\n <uiButton\n type=\"submit\"\n color=\"primary\"\n :loading=\"loading\"\n >\n Submit\n </uiButton>\n </slot>\n </div>\n </form>\n</template>\n","<template>\n <uiDateRange\n :id=\"id\"\n :loading=\"loading\"\n :literals=\"literals\"\n :values=\"internalValues\"\n :color=\"color\"\n :error=\"error\"\n :disabled=\"disabled\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n @uiDateRangeButtonClicked=\"handleSearch\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } from 'vue';\nimport { uiDateRange } from '@hotelinking/ui';\n\nexport interface DateRangeValue {\n from: Date | string;\n to: Date | string;\n}\n\nexport interface DateRangeLiterals {\n from: string;\n to: string;\n search: string;\n}\n\ninterface Props {\n id?: string;\n modelValue?: DateRangeValue;\n literals?: DateRangeLiterals;\n loading?: boolean;\n color?: 'primary' | 'secondary' | 'light' | 'green' | 'yellow' | 'red' | 'black' | 'gray' | 'white';\n error?: string;\n disabled?: boolean;\n label?: string;\n placeholder?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n id: () => `date-range-${Math.random().toString(36).substr(2, 9)}`,\n loading: false,\n literals: () => ({\n from: 'From',\n to: 'To',\n search: 'Search'\n }),\n modelValue: () => ({\n from: '',\n to: new Date().toISOString().slice(0, 16)\n })\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: DateRangeValue | undefined];\n 'search': [value: DateRangeValue | undefined];\n 'change': [value: DateRangeValue | undefined];\n}>();\n\n// Internal state\nconst internalValues = ref<DateRangeValue>({\n from: props.modelValue?.from || '',\n to: props.modelValue?.to || new Date().toISOString().slice(0, 16)\n});\n\n// Watch for external changes\nwatch(() => props.modelValue, (newValue) => {\n if (newValue) {\n internalValues.value = {\n from: newValue.from || '',\n to: newValue.to || new Date().toISOString().slice(0, 16)\n };\n }\n}, { deep: true });\n\n// Handle search button click\nfunction handleSearch(dates: DateRangeValue | undefined) {\n emit('update:modelValue', dates);\n emit('search', dates);\n emit('change', dates);\n}\n\n// Exposed methods\nfunction reset() {\n const resetValue: DateRangeValue = {\n from: '',\n to: new Date().toISOString().slice(0, 16)\n };\n internalValues.value = resetValue;\n emit('update:modelValue', resetValue);\n}\n\nfunction getValue() {\n return internalValues.value;\n}\n\nfunction setValue(value: DateRangeValue) {\n internalValues.value = value;\n emit('update:modelValue', value);\n}\n\ndefineExpose({\n reset,\n getValue,\n setValue\n});\n</script>\n"],"names":["_createElementBlock","_openBlock","_toDisplayString","_Fragment","_createBlock","_unref","_createElementVNode","_renderSlot","_createVNode"],"mappings":"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"}
1
+ {"version":3,"file":"DateRange.vue_vue_type_script_setup_true_lang-BLVg1Hah.js","sources":["../src/forms/JsonSchemaForm/JsonSchemaForm.vue","../src/forms/DateRange/DateRange.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport _Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\nimport {\n uiInput,\n uiSelect,\n uiToggle,\n uiRangeSlider,\n uiTextArea,\n uiButton\n} from '@hotelinking/ui';\n\n// Handle ESM/CJS interop for ajv\nconst Ajv = (_Ajv as unknown as { default: typeof _Ajv }).default ?? _Ajv;\n\n// Initialize AJV for JSON Schema validation with format support\nconst ajv = new Ajv({ allErrors: true });\naddFormats(ajv); // Add support for format keywords like \"email\", \"uri\", \"date\", etc.\n\ninterface JsonSchema {\n type: string;\n properties?: Record<string, any>;\n required?: string[];\n title?: string;\n description?: string;\n}\n\ninterface Props {\n schema: JsonSchema;\n modelValue?: Record<string, any>;\n uiSchema?: Record<string, any>;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: () => ({}),\n uiSchema: () => ({}),\n loading: false\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: Record<string, any>];\n 'validation-error': [errors: Array<{ field: string; message: string }>];\n 'submit': [value: Record<string, any>];\n}>();\n\n// Internal form data\nconst formData = computed({\n get: () => props.modelValue,\n set: (value: Record<string, any>) => {\n emit('update:modelValue', value);\n }\n});\n\nconst errors = ref<Record<string, string>>({});\nconst touched = ref<Record<string, boolean>>({});\n\n// Get widget type from UI schema or infer from field schema\nfunction getWidget(fieldName: string): string {\n const uiSchemaField = props.uiSchema[fieldName];\n if (uiSchemaField?.['ui:widget']) {\n return uiSchemaField['ui:widget'];\n }\n \n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema) return 'text';\n \n // Infer widget from schema\n if (fieldSchema.type === 'boolean') return 'toggle';\n if (fieldSchema.type === 'number' || fieldSchema.type === 'integer') {\n // Only use slider if explicitly specified in uiSchema\n // Don't auto-infer from min/max presence\n return 'number';\n }\n if (fieldSchema.type === 'string') {\n if (fieldSchema.enum) return 'select';\n if (fieldSchema.format === 'email') return 'email';\n if (fieldSchema.format === 'uri') return 'url';\n if (fieldSchema.minLength && fieldSchema.minLength > 100) return 'textarea';\n }\n if (fieldSchema.type === 'array') return 'array';\n if (fieldSchema.type === 'object') return 'object';\n \n return 'text';\n}\n\n// Get input type for uiInput component\nfunction getInputType(fieldName: string): 'text' | 'email' | 'password' | 'number' | 'date' | 'datetime-local' {\n const widget = getWidget(fieldName);\n \n if (widget === 'password') return 'password';\n if (widget === 'email') return 'email';\n if (widget === 'number') return 'number';\n if (widget === 'date') return 'date';\n if (widget === 'datetime-local') return 'datetime-local';\n \n return 'text';\n}\n\n// Get field color based on validation state (computed for reactivity)\nfunction getFieldColor(fieldName: string): 'gray' | 'green' | 'red' | 'yellow' {\n // Check for errors first (most important)\n if (errors.value[fieldName]) return 'red';\n \n // If field has been touched and has a valid value, show green\n if (touched.value[fieldName]) {\n const value = formData.value[fieldName];\n if (isRequired(fieldName) && value !== undefined && value !== null && value !== '') {\n return 'green';\n }\n }\n \n // Default to gray\n return 'gray';\n}\n\n// Check if field is required\nfunction isRequired(fieldName: string): boolean {\n return props.schema.required?.includes(fieldName) ?? false;\n}\n\n// Get field label\nfunction getFieldLabel(fieldName: string): string {\n const fieldSchema = props.schema.properties?.[fieldName];\n return fieldSchema?.title || fieldName;\n}\n\n// Get field description\nfunction getFieldDescription(fieldName: string): string {\n const fieldSchema = props.schema.properties?.[fieldName];\n return fieldSchema?.description || '';\n}\n\n// Get placeholder from UI schema\nfunction getPlaceholder(fieldName: string): string {\n return props.uiSchema[fieldName]?.['ui:placeholder'] || '';\n}\n\n// Get autocomplete attribute for better UX (especially for passwords)\n// Following https://www.chromium.org/developers/design-documents/create-amazing-password-forms/\nfunction getAutocomplete(fieldName: string): string | undefined {\n const widget = getWidget(fieldName);\n const fieldSchema = props.schema.properties?.[fieldName];\n \n // Check if explicitly set in uiSchema\n if (props.uiSchema[fieldName]?.['ui:autocomplete']) {\n return props.uiSchema[fieldName]['ui:autocomplete'];\n }\n \n // Auto-detect based on field name and type\n const lowerFieldName = fieldName.toLowerCase();\n \n if (widget === 'email' || fieldSchema?.format === 'email') {\n return 'email';\n }\n \n if (widget === 'password') {\n // Check for common password field patterns\n if (lowerFieldName.includes('new') || lowerFieldName.includes('confirm')) {\n return 'new-password';\n }\n if (lowerFieldName.includes('current') || lowerFieldName === 'password') {\n return 'current-password';\n }\n return 'current-password'; // Default for password fields\n }\n \n // Common autocomplete values\n if (lowerFieldName.includes('username') || lowerFieldName === 'user') {\n return 'username';\n }\n if (lowerFieldName.includes('name')) {\n if (lowerFieldName.includes('first')) return 'given-name';\n if (lowerFieldName.includes('last')) return 'family-name';\n return 'name';\n }\n if (lowerFieldName.includes('phone') || lowerFieldName.includes('tel')) {\n return 'tel';\n }\n if (lowerFieldName.includes('address')) {\n return 'street-address';\n }\n if (lowerFieldName.includes('city')) {\n return 'address-level2';\n }\n if (lowerFieldName.includes('country')) {\n return 'country-name';\n }\n if (lowerFieldName.includes('postal') || lowerFieldName.includes('zip')) {\n return 'postal-code';\n }\n \n return undefined;\n}\n\n// Validate form data against schema using AJV\nfunction validate(): Array<{ field: string; message: string }> {\n const validationErrors: Array<{ field: string; message: string }> = [];\n errors.value = {};\n\n // Compile and validate using AJV\n const validateFn = ajv.compile(props.schema);\n const valid = validateFn(formData.value);\n\n if (!valid && validateFn.errors) {\n for (const error of validateFn.errors) {\n // Extract field name from instancePath (e.g., \"/fieldName\" -> \"fieldName\")\n const field = error.instancePath.replace(/^\\//, '') || error.params.missingProperty || 'form';\n \n // Generate user-friendly error message\n let message = '';\n \n if (error.keyword === 'required') {\n const missingField = error.params.missingProperty;\n message = `${getFieldLabel(missingField)} is required`;\n errors.value[missingField] = message;\n validationErrors.push({ field: missingField, message });\n } else if (error.keyword === 'type') {\n message = `${getFieldLabel(field)} must be a ${error.params.type}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'minimum') {\n message = `${getFieldLabel(field)} must be at least ${error.params.limit}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'maximum') {\n message = `${getFieldLabel(field)} must be at most ${error.params.limit}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'minLength') {\n message = `${getFieldLabel(field)} must be at least ${error.params.limit} characters`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'maxLength') {\n message = `${getFieldLabel(field)} must be at most ${error.params.limit} characters`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'format') {\n message = `${getFieldLabel(field)} must be a valid ${error.params.format}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else if (error.keyword === 'enum') {\n message = `${getFieldLabel(field)} must be one of: ${error.params.allowedValues.join(', ')}`;\n errors.value[field] = message;\n validationErrors.push({ field, message });\n } else {\n // Generic error message\n message = error.message || 'Invalid value';\n errors.value[field] = message;\n validationErrors.push({ field, message });\n }\n }\n }\n\n return validationErrors;\n}\n\n// Handle form submission\nfunction handleSubmit(event: Event) {\n event.preventDefault();\n \n const validationErrors = validate();\n if (validationErrors.length > 0) {\n emit('validation-error', validationErrors);\n return;\n }\n \n emit('submit', formData.value);\n}\n\n// Update field value\nfunction updateField(field: string, value: any) {\n touched.value[field] = true;\n \n // Update formData by emitting the new value\n const newData = {\n ...formData.value,\n [field]: value\n };\n emit('update:modelValue', newData);\n \n // Validate field on change with the new value\n validateFieldWithValue(field, value);\n}\n\n// Validate a single field using AJV (reads from formData)\nfunction validateField(fieldName: string) {\n validateFieldWithValue(fieldName, formData.value[fieldName]);\n}\n\n// Validate a single field with a specific value\nfunction validateFieldWithValue(fieldName: string, fieldValue: any) {\n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema) return;\n \n // Clear existing error\n delete errors.value[fieldName];\n \n // If field is empty/null/undefined and required, show required error\n if (isRequired(fieldName) && (fieldValue === undefined || fieldValue === null || fieldValue === '')) {\n errors.value[fieldName] = `${getFieldLabel(fieldName)} is required`;\n return;\n }\n \n // If field is empty and not required, no validation needed\n if (fieldValue === undefined || fieldValue === null || fieldValue === '') {\n return;\n }\n \n // Create a mini schema for just this field (without required)\n const singleFieldSchema = {\n type: 'object',\n properties: {\n [fieldName]: fieldSchema\n }\n };\n \n // Validate just this field\n const validateFn = ajv.compile(singleFieldSchema);\n const valid = validateFn({ [fieldName]: fieldValue });\n \n if (!valid && validateFn.errors) {\n for (const error of validateFn.errors) {\n let message = '';\n \n if (error.keyword === 'type') {\n message = `${getFieldLabel(fieldName)} must be a ${error.params.type}`;\n } else if (error.keyword === 'minimum') {\n message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit}`;\n } else if (error.keyword === 'maximum') {\n message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit}`;\n } else if (error.keyword === 'minLength') {\n message = `${getFieldLabel(fieldName)} must be at least ${error.params.limit} characters`;\n } else if (error.keyword === 'maxLength') {\n message = `${getFieldLabel(fieldName)} must be at most ${error.params.limit} characters`;\n } else if (error.keyword === 'format') {\n message = `${getFieldLabel(fieldName)} must be a valid ${error.params.format}`;\n } else if (error.keyword === 'enum') {\n message = `${getFieldLabel(fieldName)} must be one of: ${error.params.allowedValues.join(', ')}`;\n } else {\n message = error.message || 'Invalid value';\n }\n \n errors.value[fieldName] = message;\n break; // Only show first error per field\n }\n }\n}\n\n// Get enum options for select\nfunction getSelectOptions(fieldName: string) {\n const fieldSchema = props.schema.properties?.[fieldName];\n if (!fieldSchema?.enum) return [];\n \n return fieldSchema.enum.map((value: any) => ({\n id: String(value),\n name: String(value),\n label: String(value)\n }));\n}\n\n// Get selected option for select\nfunction getSelectedOption(fieldName: string) {\n const value = formData.value[fieldName];\n if (!value) {\n // Return first option as default if available\n const options = getSelectOptions(fieldName);\n return options.length > 0 ? options[0] : { id: '', name: '', label: '' };\n }\n \n return {\n id: String(value),\n name: String(value),\n label: String(value)\n };\n}\n\n// Array field helpers\nfunction addArrayItem(fieldName: string) {\n const currentArray = formData.value[fieldName] || [];\n updateField(fieldName, [...currentArray, '']);\n}\n\nfunction removeArrayItem(fieldName: string, index: number) {\n const currentArray = formData.value[fieldName] || [];\n const newArray = currentArray.filter((_: any, i: number) => i !== index);\n updateField(fieldName, newArray);\n}\n\nfunction updateArrayItem(fieldName: string, index: number, value: any) {\n const currentArray = formData.value[fieldName] || [];\n const newArray = [...currentArray];\n newArray[index] = value;\n updateField(fieldName, newArray);\n}\n\n// Expose methods\ndefineExpose({\n validate,\n validateField,\n reset: () => { \n emit('update:modelValue', {});\n errors.value = {}; \n touched.value = {};\n },\n // Expose internal state for testing\n formData,\n errors,\n touched,\n // Expose helper methods for testing\n getFieldLabel,\n getFieldDescription,\n isRequired,\n getWidget,\n getInputType,\n getFieldColor,\n getPlaceholder,\n getSelectOptions,\n getSelectedOption,\n updateField\n});\n</script>\n\n<template>\n <form @submit=\"handleSubmit\" class=\"space-y-6\">\n <!-- Form Title and Description -->\n <div v-if=\"schema.title || schema.description\" class=\"mb-6\">\n <h2 v-if=\"schema.title\" class=\"text-2xl font-bold text-gray-900 mb-2\">\n {{ schema.title }}\n </h2>\n <p v-if=\"schema.description\" class=\"text-gray-600\">\n {{ schema.description }}\n </p>\n </div>\n\n <!-- Form Fields -->\n <div v-if=\"schema.properties\" class=\"space-y-6\">\n <div\n v-for=\"(fieldSchema, fieldName) in schema.properties\"\n :key=\"fieldName\"\n >\n <!-- Text/Email/URL/Password Input -->\n <uiInput\n v-if=\"['text', 'email', 'url', 'password'].includes(getWidget(fieldName))\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n :type=\"getInputType(fieldName)\"\n :value=\"formData[fieldName] || ''\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @input-changed=\"updateField(fieldName, $event.value)\"\n />\n\n <!-- Number Input -->\n <uiInput\n v-else-if=\"getWidget(fieldName) === 'number'\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n type=\"number\"\n :value=\"String(formData[fieldName] ?? '')\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n :min=\"schema.properties?.[fieldName]?.minimum\"\n :max=\"schema.properties?.[fieldName]?.maximum\"\n @input-changed=\"updateField(fieldName, $event.value === '' ? null : Number($event.value))\"\n />\n\n <!-- Textarea -->\n <uiTextArea\n v-else-if=\"getWidget(fieldName) === 'textarea'\"\n :name=\"fieldName\"\n :label=\"getFieldLabel(fieldName)\"\n :value=\"formData[fieldName] || ''\"\n :placeholder=\"getPlaceholder(fieldName)\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n :rows=\"4\"\n @input-changed=\"updateField(fieldName, $event.value)\"\n />\n\n <!-- Select Dropdown -->\n <uiSelect\n v-else-if=\"getWidget(fieldName) === 'select'\"\n :label=\"getFieldLabel(fieldName)\"\n :items=\"getSelectOptions(fieldName)\"\n :select=\"getSelectedOption(fieldName)\"\n :placeholder=\"getPlaceholder(fieldName) || 'Select an option'\"\n :error=\"errors[fieldName]\"\n :color=\"getFieldColor(fieldName)\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @select-changed=\"(item: any) => updateField(fieldName, item.id)\"\n />\n\n <!-- Toggle (Boolean) -->\n <uiToggle\n v-else-if=\"getWidget(fieldName) === 'toggle'\"\n :item=\"{\n title: getFieldLabel(fieldName),\n subtitle: getFieldDescription(fieldName),\n action: fieldName\n }\"\n :checked=\"formData[fieldName]\"\n :loading=\"loading\"\n @toggle-changed=\"updateField(fieldName, $event.active)\"\n />\n\n <!-- Checkbox (Boolean alternative) -->\n <div v-else-if=\"getWidget(fieldName) === 'checkbox'\" class=\"flex items-start\">\n <input\n :id=\"fieldName\"\n type=\"checkbox\"\n :checked=\"formData[fieldName]\"\n :disabled=\"loading\"\n @change=\"updateField(fieldName, ($event.target as HTMLInputElement).checked)\"\n class=\"h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded mt-1\"\n />\n <label :for=\"fieldName\" class=\"ml-2 block\">\n <span class=\"text-sm font-medium text-gray-700\">\n {{ getFieldLabel(fieldName) }}\n <span v-if=\"isRequired(fieldName)\" class=\"text-red-500\">*</span>\n </span>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-500\">\n {{ getFieldDescription(fieldName) }}\n </p>\n </label>\n </div>\n\n <!-- Range Slider -->\n <uiRangeSlider\n v-else-if=\"getWidget(fieldName) === 'slider'\"\n :label=\"getFieldLabel(fieldName)\"\n :min=\"schema.properties[fieldName].minimum ?? 0\"\n :max=\"schema.properties[fieldName].maximum ?? 100\"\n :slider-value=\"formData[fieldName] ?? schema.properties[fieldName].minimum ?? 0\"\n :loading=\"loading\"\n :required-text=\"isRequired(fieldName) ? '*' : undefined\"\n @sliderUpdated=\"updateField(fieldName, $event)\"\n />\n\n <!-- Array (Simple list) -->\n <div v-else-if=\"getWidget(fieldName) === 'array'\" class=\"space-y-2\">\n <label class=\"block text-sm font-medium text-gray-700\">\n {{ getFieldLabel(fieldName) }}\n <span v-if=\"isRequired(fieldName)\" class=\"text-red-500\">*</span>\n </label>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-500 mb-2\">\n {{ getFieldDescription(fieldName) }}\n </p>\n <div v-if=\"errors[fieldName]\" class=\"text-sm text-red-600 mb-2\">\n {{ errors[fieldName] }}\n </div>\n <div class=\"space-y-2\">\n <div\n v-for=\"(item, index) in (formData[fieldName] || [])\"\n :key=\"index\"\n class=\"flex gap-2\"\n >\n <input\n type=\"text\"\n :value=\"item\"\n :disabled=\"loading\"\n @input=\"updateArrayItem(fieldName, index, ($event.target as HTMLInputElement).value)\"\n class=\"flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <button\n type=\"button\"\n @click=\"removeArrayItem(fieldName, index)\"\n :disabled=\"loading\"\n class=\"px-3 py-2 text-red-600 hover:text-red-800 border border-red-300 rounded-md\"\n >\n Remove\n </button>\n </div>\n </div>\n <button\n type=\"button\"\n @click=\"addArrayItem(fieldName)\"\n :disabled=\"loading\"\n class=\"mt-2 px-4 py-2 text-sm text-blue-600 hover:text-blue-800 border border-blue-300 rounded-md\"\n >\n + Add Item\n </button>\n </div>\n\n <!-- Nested Object (Simple rendering) -->\n <div v-else-if=\"getWidget(fieldName) === 'object' || getWidget(fieldName) === 'card'\" class=\"border border-gray-200 rounded-lg p-4 space-y-4\">\n <div>\n <h3 class=\"text-lg font-semibold text-gray-900 mb-1\">\n {{ getFieldLabel(fieldName) }}\n </h3>\n <p v-if=\"getFieldDescription(fieldName)\" class=\"text-sm text-gray-600 mb-4\">\n {{ getFieldDescription(fieldName) }}\n </p>\n </div>\n <div class=\"space-y-4 pl-4 border-l-2 border-gray-200\">\n <!-- Recursively render nested fields -->\n <div\n v-for=\"(subSchema, subName) in fieldSchema.properties\"\n :key=\"subName\"\n >\n <!-- Nested field rendering would go here -->\n <p class=\"text-sm text-gray-500\">\n Nested field: {{ subName }} (type: {{ subSchema.type }})\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex justify-end gap-3 pt-6 border-t\">\n <slot name=\"actions\">\n <uiButton\n type=\"submit\"\n color=\"primary\"\n :loading=\"loading\"\n >\n Submit\n </uiButton>\n </slot>\n </div>\n </form>\n</template>\n","<template>\n <uiDateRange\n :id=\"id\"\n :loading=\"loading\"\n :literals=\"literals\"\n :values=\"internalValues\"\n :color=\"color\"\n :error=\"error\"\n :disabled=\"disabled\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n @uiDateRangeButtonClicked=\"handleSearch\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } from 'vue';\nimport { uiDateRange } from '@hotelinking/ui';\n\nexport interface DateRangeValue {\n from: Date | string;\n to: Date | string;\n}\n\nexport interface DateRangeLiterals {\n from: string;\n to: string;\n search: string;\n}\n\ninterface Props {\n id?: string;\n modelValue?: DateRangeValue;\n literals?: DateRangeLiterals;\n loading?: boolean;\n color?: 'primary' | 'secondary' | 'light' | 'green' | 'yellow' | 'red' | 'black' | 'gray' | 'white';\n error?: string;\n disabled?: boolean;\n label?: string;\n placeholder?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n id: () => `date-range-${Math.random().toString(36).substr(2, 9)}`,\n loading: false,\n literals: () => ({\n from: 'From',\n to: 'To',\n search: 'Search'\n }),\n modelValue: () => ({\n from: '',\n to: new Date().toISOString().slice(0, 16)\n })\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: DateRangeValue | undefined];\n 'search': [value: DateRangeValue | undefined];\n 'change': [value: DateRangeValue | undefined];\n}>();\n\n// Internal state\nconst internalValues = ref<DateRangeValue>({\n from: props.modelValue?.from || '',\n to: props.modelValue?.to || new Date().toISOString().slice(0, 16)\n});\n\n// Watch for external changes\nwatch(() => props.modelValue, (newValue) => {\n if (newValue) {\n internalValues.value = {\n from: newValue.from || '',\n to: newValue.to || new Date().toISOString().slice(0, 16)\n };\n }\n}, { deep: true });\n\n// Handle search button click\nfunction handleSearch(dates: DateRangeValue | undefined) {\n emit('update:modelValue', dates);\n emit('search', dates);\n emit('change', dates);\n}\n\n// Exposed methods\nfunction reset() {\n const resetValue: DateRangeValue = {\n from: '',\n to: new Date().toISOString().slice(0, 16)\n };\n internalValues.value = resetValue;\n emit('update:modelValue', resetValue);\n}\n\nfunction getValue() {\n return internalValues.value;\n}\n\nfunction setValue(value: DateRangeValue) {\n internalValues.value = value;\n emit('update:modelValue', value);\n}\n\ndefineExpose({\n reset,\n getValue,\n setValue\n});\n</script>\n"],"names":["_createElementBlock","_openBlock","_toDisplayString","_Fragment","_createBlock","_unref","_createElementVNode","_renderSlot","_createVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,UAAM,MAAO,KAA6C,WAAW;AAGrE,UAAM,MAAM,IAAI,IAAI,EAAE,WAAW,MAAM;AACvC,eAAW,GAAG;AAiBd,UAAM,QAAQ;AAMd,UAAM,OAAO;AAOb,UAAM,WAAW,SAAS;AAAA,MACxB,KAAK,MAAM,MAAM;AAAA,MACjB,KAAK,CAAC,UAA+B;AACnC,aAAK,qBAAqB,KAAK;AAAA,MACjC;AAAA,IAAA,CACD;AAED,UAAM,SAAS,IAA4B,EAAE;AAC7C,UAAM,UAAU,IAA6B,EAAE;AAG/C,aAAS,UAAU,WAA2B;;AAC5C,YAAM,gBAAgB,MAAM,SAAS,SAAS;AAC9C,UAAI,+CAAgB,cAAc;AAChC,eAAO,cAAc,WAAW;AAAA,MAClC;AAEA,YAAM,eAAc,WAAM,OAAO,eAAb,mBAA0B;AAC9C,UAAI,CAAC,YAAa,QAAO;AAGzB,UAAI,YAAY,SAAS,UAAW,QAAO;AAC3C,UAAI,YAAY,SAAS,YAAY,YAAY,SAAS,WAAW;AAGnE,eAAO;AAAA,MACT;AACA,UAAI,YAAY,SAAS,UAAU;AACjC,YAAI,YAAY,KAAM,QAAO;AAC7B,YAAI,YAAY,WAAW,QAAS,QAAO;AAC3C,YAAI,YAAY,WAAW,MAAO,QAAO;AACzC,YAAI,YAAY,aAAa,YAAY,YAAY,IAAK,QAAO;AAAA,MACnE;AACA,UAAI,YAAY,SAAS,QAAS,QAAO;AACzC,UAAI,YAAY,SAAS,SAAU,QAAO;AAE1C,aAAO;AAAA,IACT;AAGA,aAAS,aAAa,WAAyF;AAC7G,YAAM,SAAS,UAAU,SAAS;AAElC,UAAI,WAAW,WAAY,QAAO;AAClC,UAAI,WAAW,QAAS,QAAO;AAC/B,UAAI,WAAW,SAAU,QAAO;AAChC,UAAI,WAAW,OAAQ,QAAO;AAC9B,UAAI,WAAW,iBAAkB,QAAO;AAExC,aAAO;AAAA,IACT;AAGA,aAAS,cAAc,WAAwD;AAE7E,UAAI,OAAO,MAAM,SAAS,EAAG,QAAO;AAGpC,UAAI,QAAQ,MAAM,SAAS,GAAG;AAC5B,cAAM,QAAQ,SAAS,MAAM,SAAS;AACtC,YAAI,WAAW,SAAS,KAAK,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AAClF,iBAAO;AAAA,QACT;AAAA,MACF;AAGA,aAAO;AAAA,IACT;AAGA,aAAS,WAAW,WAA4B;;AAC9C,eAAO,WAAM,OAAO,aAAb,mBAAuB,SAAS,eAAc;AAAA,IACvD;AAGA,aAAS,cAAc,WAA2B;;AAChD,YAAM,eAAc,WAAM,OAAO,eAAb,mBAA0B;AAC9C,cAAO,2CAAa,UAAS;AAAA,IAC/B;AAGA,aAAS,oBAAoB,WAA2B;;AACtD,YAAM,eAAc,WAAM,OAAO,eAAb,mBAA0B;AAC9C,cAAO,2CAAa,gBAAe;AAAA,IACrC;AAGA,aAAS,eAAe,WAA2B;;AACjD,eAAO,WAAM,SAAS,SAAS,MAAxB,mBAA4B,sBAAqB;AAAA,IAC1D;AA4DA,aAAS,WAAsD;AAC7D,YAAM,mBAA8D,CAAA;AACpE,aAAO,QAAQ,CAAA;AAGf,YAAM,aAAa,IAAI,QAAQ,MAAM,MAAM;AAC3C,YAAM,QAAQ,WAAW,SAAS,KAAK;AAEvC,UAAI,CAAC,SAAS,WAAW,QAAQ;AAC/B,mBAAW,SAAS,WAAW,QAAQ;AAErC,gBAAM,QAAQ,MAAM,aAAa,QAAQ,OAAO,EAAE,KAAK,MAAM,OAAO,mBAAmB;AAGvF,cAAI,UAAU;AAEd,cAAI,MAAM,YAAY,YAAY;AAChC,kBAAM,eAAe,MAAM,OAAO;AAClC,sBAAU,GAAG,cAAc,YAAY,CAAC;AACxC,mBAAO,MAAM,YAAY,IAAI;AAC7B,6BAAiB,KAAK,EAAE,OAAO,cAAc,SAAS;AAAA,UACxD,WAAW,MAAM,YAAY,QAAQ;AACnC,sBAAU,GAAG,cAAc,KAAK,CAAC,cAAc,MAAM,OAAO,IAAI;AAChE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,WAAW;AACtC,sBAAU,GAAG,cAAc,KAAK,CAAC,qBAAqB,MAAM,OAAO,KAAK;AACxE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,WAAW;AACtC,sBAAU,GAAG,cAAc,KAAK,CAAC,oBAAoB,MAAM,OAAO,KAAK;AACvE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,aAAa;AACxC,sBAAU,GAAG,cAAc,KAAK,CAAC,qBAAqB,MAAM,OAAO,KAAK;AACxE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,aAAa;AACxC,sBAAU,GAAG,cAAc,KAAK,CAAC,oBAAoB,MAAM,OAAO,KAAK;AACvE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,UAAU;AACrC,sBAAU,GAAG,cAAc,KAAK,CAAC,oBAAoB,MAAM,OAAO,MAAM;AACxE,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,WAAW,MAAM,YAAY,QAAQ;AACnC,sBAAU,GAAG,cAAc,KAAK,CAAC,oBAAoB,MAAM,OAAO,cAAc,KAAK,IAAI,CAAC;AAC1F,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C,OAAO;AAEL,sBAAU,MAAM,WAAW;AAC3B,mBAAO,MAAM,KAAK,IAAI;AACtB,6BAAiB,KAAK,EAAE,OAAO,QAAA,CAAS;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAGA,aAAS,aAAa,OAAc;AAClC,YAAM,eAAA;AAEN,YAAM,mBAAmB,SAAA;AACzB,UAAI,iBAAiB,SAAS,GAAG;AAC/B,aAAK,oBAAoB,gBAAgB;AACzC;AAAA,MACF;AAEA,WAAK,UAAU,SAAS,KAAK;AAAA,IAC/B;AAGA,aAAS,YAAY,OAAe,OAAY;AAC9C,cAAQ,MAAM,KAAK,IAAI;AAGvB,YAAM,UAAU;AAAA,QACd,GAAG,SAAS;AAAA,QACZ,CAAC,KAAK,GAAG;AAAA,MAAA;AAEX,WAAK,qBAAqB,OAAO;AAGjC,6BAAuB,OAAO,KAAK;AAAA,IACrC;AAGA,aAAS,cAAc,WAAmB;AACxC,6BAAuB,WAAW,SAAS,MAAM,SAAS,CAAC;AAAA,IAC7D;AAGA,aAAS,uBAAuB,WAAmB,YAAiB;;AAClE,YAAM,eAAc,WAAM,OAAO,eAAb,mBAA0B;AAC9C,UAAI,CAAC,YAAa;AAGlB,aAAO,OAAO,MAAM,SAAS;AAG7B,UAAI,WAAW,SAAS,MAAM,eAAe,UAAa,eAAe,QAAQ,eAAe,KAAK;AACnG,eAAO,MAAM,SAAS,IAAI,GAAG,cAAc,SAAS,CAAC;AACrD;AAAA,MACF;AAGA,UAAI,eAAe,UAAa,eAAe,QAAQ,eAAe,IAAI;AACxE;AAAA,MACF;AAGA,YAAM,oBAAoB;AAAA,QACxB,MAAM;AAAA,QACN,YAAY;AAAA,UACV,CAAC,SAAS,GAAG;AAAA,QAAA;AAAA,MACf;AAIF,YAAM,aAAa,IAAI,QAAQ,iBAAiB;AAChD,YAAM,QAAQ,WAAW,EAAE,CAAC,SAAS,GAAG,YAAY;AAEpD,UAAI,CAAC,SAAS,WAAW,QAAQ;AAC/B,mBAAW,SAAS,WAAW,QAAQ;AACrC,cAAI,UAAU;AAEd,cAAI,MAAM,YAAY,QAAQ;AAC5B,sBAAU,GAAG,cAAc,SAAS,CAAC,cAAc,MAAM,OAAO,IAAI;AAAA,UACtE,WAAW,MAAM,YAAY,WAAW;AACtC,sBAAU,GAAG,cAAc,SAAS,CAAC,qBAAqB,MAAM,OAAO,KAAK;AAAA,UAC9E,WAAW,MAAM,YAAY,WAAW;AACtC,sBAAU,GAAG,cAAc,SAAS,CAAC,oBAAoB,MAAM,OAAO,KAAK;AAAA,UAC7E,WAAW,MAAM,YAAY,aAAa;AACxC,sBAAU,GAAG,cAAc,SAAS,CAAC,qBAAqB,MAAM,OAAO,KAAK;AAAA,UAC9E,WAAW,MAAM,YAAY,aAAa;AACxC,sBAAU,GAAG,cAAc,SAAS,CAAC,oBAAoB,MAAM,OAAO,KAAK;AAAA,UAC7E,WAAW,MAAM,YAAY,UAAU;AACrC,sBAAU,GAAG,cAAc,SAAS,CAAC,oBAAoB,MAAM,OAAO,MAAM;AAAA,UAC9E,WAAW,MAAM,YAAY,QAAQ;AACnC,sBAAU,GAAG,cAAc,SAAS,CAAC,oBAAoB,MAAM,OAAO,cAAc,KAAK,IAAI,CAAC;AAAA,UAChG,OAAO;AACL,sBAAU,MAAM,WAAW;AAAA,UAC7B;AAEA,iBAAO,MAAM,SAAS,IAAI;AAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,aAAS,iBAAiB,WAAmB;;AAC3C,YAAM,eAAc,WAAM,OAAO,eAAb,mBAA0B;AAC9C,UAAI,EAAC,2CAAa,MAAM,QAAO,CAAA;AAE/B,aAAO,YAAY,KAAK,IAAI,CAAC,WAAgB;AAAA,QAC3C,IAAI,OAAO,KAAK;AAAA,QAChB,MAAM,OAAO,KAAK;AAAA,QAClB,OAAO,OAAO,KAAK;AAAA,MAAA,EACnB;AAAA,IACJ;AAGA,aAAS,kBAAkB,WAAmB;AAC5C,YAAM,QAAQ,SAAS,MAAM,SAAS;AACtC,UAAI,CAAC,OAAO;AAEV,cAAM,UAAU,iBAAiB,SAAS;AAC1C,eAAO,QAAQ,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,IAAI,OAAO,GAAA;AAAA,MACtE;AAEA,aAAO;AAAA,QACL,IAAI,OAAO,KAAK;AAAA,QAChB,MAAM,OAAO,KAAK;AAAA,QAClB,OAAO,OAAO,KAAK;AAAA,MAAA;AAAA,IAEvB;AAGA,aAAS,aAAa,WAAmB;AACvC,YAAM,eAAe,SAAS,MAAM,SAAS,KAAK,CAAA;AAClD,kBAAY,WAAW,CAAC,GAAG,cAAc,EAAE,CAAC;AAAA,IAC9C;AAEA,aAAS,gBAAgB,WAAmB,OAAe;AACzD,YAAM,eAAe,SAAS,MAAM,SAAS,KAAK,CAAA;AAClD,YAAM,WAAW,aAAa,OAAO,CAAC,GAAQ,MAAc,MAAM,KAAK;AACvE,kBAAY,WAAW,QAAQ;AAAA,IACjC;AAEA,aAAS,gBAAgB,WAAmB,OAAe,OAAY;AACrE,YAAM,eAAe,SAAS,MAAM,SAAS,KAAK,CAAA;AAClD,YAAM,WAAW,CAAC,GAAG,YAAY;AACjC,eAAS,KAAK,IAAI;AAClB,kBAAY,WAAW,QAAQ;AAAA,IACjC;AAGA,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA,OAAO,MAAM;AACX,aAAK,qBAAqB,EAAE;AAC5B,eAAO,QAAQ,CAAA;AACf,gBAAQ,QAAQ,CAAA;AAAA,MAClB;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;;0BAICA,mBA+MO,QAAA;AAAA,QA/MA,UAAQ;AAAA,QAAc,OAAM;AAAA,MAAA;QAEtB,QAAA,OAAO,SAAS,QAAA,OAAO,eAAlCC,aAAAD,mBAOM,OAPN,YAOM;AAAA,UANM,QAAA,OAAO,SAAjBC,UAAA,GAAAD,mBAEK,MAFL,YAEKE,gBADA,QAAA,OAAO,KAAK,GAAA,CAAA;UAER,QAAA,OAAO,eAAhBD,UAAA,GAAAD,mBAEI,KAFJ,YAEIE,gBADC,QAAA,OAAO,WAAW,GAAA,CAAA;;QAKd,QAAA,OAAO,cAAlBD,aAAAD,mBAqLM,OArLN,YAqLM;AAAA,WApLJC,UAAA,IAAA,GAAAD,mBAmLMG,2BAlL+B,QAAA,OAAO,YAAU,CAA5C,aAAa,cAAS;;gCADhCH,mBAmLM,OAAA,EAjLH,KAAK,aAAS;AAAA,mDAI8B,SAAS,UAAU,SAAS,CAAA,kBADzEI,YAYEC,MAAA,OAAA,GAAA;AAAA;gBAVC,MAAM;AAAA,gBACN,OAAO,cAAc,SAAS;AAAA,gBAC9B,MAAM,aAAa,SAAS;AAAA,gBAC5B,OAAO,SAAA,MAAS,SAAS,KAAA;AAAA,gBACzB,aAAa,eAAe,SAAS;AAAA,gBACrC,OAAO,OAAA,MAAO,SAAS;AAAA,gBACvB,OAAO,cAAc,SAAS;AAAA,gBAC9B,SAAS,QAAA;AAAA,gBACT,iBAAe,WAAW,SAAS,UAAU;AAAA,gBAC7C,4BAAe,YAAY,WAAW,OAAO,KAAK;AAAA,cAAA,kIAKxC,UAAU,SAAS,MAAA,yBADhCD,YAcEC,MAAA,OAAA,GAAA;AAAA;gBAZC,MAAM;AAAA,gBACN,OAAO,cAAc,SAAS;AAAA,gBAC/B,MAAK;AAAA,gBACJ,OAAO,OAAO,SAAA,MAAS,SAAS,KAAA,EAAA;AAAA,gBAChC,aAAa,eAAe,SAAS;AAAA,gBACrC,OAAO,OAAA,MAAO,SAAS;AAAA,gBACvB,OAAO,cAAc,SAAS;AAAA,gBAC9B,SAAS,QAAA;AAAA,gBACT,iBAAe,WAAW,SAAS,UAAU;AAAA,gBAC7C,MAAK,mBAAA,OAAO,eAAP,mBAAoB,eAApB,mBAAgC;AAAA,gBACrC,MAAK,mBAAA,OAAO,eAAP,mBAAoB,eAApB,mBAAgC;AAAA,gBACrC,gBAAa,CAAA,WAAE,YAAY,WAAW,OAAO,UAAK,KAAA,OAAiB,OAAO,OAAO,KAAK,CAAA;AAAA,cAAA,wIAK5E,UAAU,SAAS,MAAA,2BADhCD,YAYEC,MAAA,UAAA,GAAA;AAAA;gBAVC,MAAM;AAAA,gBACN,OAAO,cAAc,SAAS;AAAA,gBAC9B,OAAO,SAAA,MAAS,SAAS,KAAA;AAAA,gBACzB,aAAa,eAAe,SAAS;AAAA,gBACrC,OAAO,OAAA,MAAO,SAAS;AAAA,gBACvB,OAAO,cAAc,SAAS;AAAA,gBAC9B,SAAS,QAAA;AAAA,gBACT,iBAAe,WAAW,SAAS,UAAU;AAAA,gBAC7C,MAAM;AAAA,gBACN,4BAAe,YAAY,WAAW,OAAO,KAAK;AAAA,cAAA,0HAKxC,UAAU,SAAS,MAAA,yBADhCD,YAWEC,MAAA,QAAA,GAAA;AAAA;gBATC,OAAO,cAAc,SAAS;AAAA,gBAC9B,OAAO,iBAAiB,SAAS;AAAA,gBACjC,QAAQ,kBAAkB,SAAS;AAAA,gBACnC,aAAa,eAAe,SAAS,KAAA;AAAA,gBACrC,OAAO,OAAA,MAAO,SAAS;AAAA,gBACvB,OAAO,cAAc,SAAS;AAAA,gBAC9B,SAAS,QAAA;AAAA,gBACT,iBAAe,WAAW,SAAS,UAAU;AAAA,gBAC7C,iBAAc,CAAG,SAAc,YAAY,WAAW,KAAK,EAAE;AAAA,cAAA,6HAKnD,UAAU,SAAS,MAAA,yBADhCD,YAUEC,MAAA,QAAA,GAAA;AAAA;gBARC,MAAI;AAAA,kBAAuB,OAAA,cAAc,SAAS;AAAA,kBAAyB,UAAA,oBAAoB,SAAS;AAAA,0BAAuB;AAAA,gBAAA;AAAA,gBAK/H,SAAS,SAAA,MAAS,SAAS;AAAA,gBAC3B,SAAS,QAAA;AAAA,gBACT,6BAAgB,YAAY,WAAW,OAAO,MAAM;AAAA,cAAA,kEAIvC,UAAU,SAAS,MAAA,cAAnCJ,aAAAD,mBAkBM,OAlBN,YAkBM;AAAA,gBAjBJM,mBAOE,SAAA;AAAA,kBANC,IAAI;AAAA,kBACL,MAAK;AAAA,kBACJ,SAAS,SAAA,MAAS,SAAS;AAAA,kBAC3B,UAAU,QAAA;AAAA,kBACV,UAAM,CAAA,WAAE,YAAY,WAAY,OAAO,OAA4B,OAAO;AAAA,kBAC3E,OAAM;AAAA,gBAAA;gBAERA,mBAQQ,SAAA;AAAA,kBARA,KAAK;AAAA,kBAAW,OAAM;AAAA,gBAAA;kBAC5BA,mBAGO,QAHP,YAGO;AAAA,oDAFF,cAAc,SAAS,CAAA,IAAI,KAC9B,CAAA;AAAA,oBAAY,WAAW,SAAS,kBAAhCN,mBAAgE,QAAhE,YAAwD,GAAC;;kBAElD,oBAAoB,SAAS,KAAtCC,UAAA,GAAAD,mBAEI,KAFJ,aAEIE,gBADC,oBAAoB,SAAS,CAAA,GAAA,CAAA;;oBAOzB,UAAU,SAAS,MAAA,yBADhCE,YASEC,MAAA,aAAA,GAAA;AAAA;gBAPC,OAAO,cAAc,SAAS;AAAA,gBAC9B,KAAK,QAAA,OAAO,WAAW,SAAS,EAAE,WAAO;AAAA,gBACzC,KAAK,QAAA,OAAO,WAAW,SAAS,EAAE,WAAO;AAAA,gBACzC,gBAAc,SAAA,MAAS,SAAS,KAAK,QAAA,OAAO,WAAW,SAAS,EAAE,WAAO;AAAA,gBACzE,SAAS,QAAA;AAAA,gBACT,iBAAe,WAAW,SAAS,UAAU;AAAA,gBAC7C,iBAAa,CAAA,WAAE,YAAY,WAAW,MAAM;AAAA,cAAA,uGAI/B,UAAU,SAAS,MAAA,WAAnCJ,aAAAD,mBA0CM,OA1CN,aA0CM;AAAA,gBAzCJM,mBAGQ,SAHR,aAGQ;AAAA,kDAFH,cAAc,SAAS,CAAA,IAAI,KAC9B,CAAA;AAAA,kBAAY,WAAW,SAAS,kBAAhCN,mBAAgE,QAAhE,aAAwD,GAAC;;gBAElD,oBAAoB,SAAS,KAAtCC,UAAA,GAAAD,mBAEI,KAFJ,aAEIE,gBADC,oBAAoB,SAAS,CAAA,GAAA,CAAA;gBAEvB,OAAA,MAAO,SAAS,KAA3BD,UAAA,GAAAD,mBAEM,OAFN,aAEME,gBADD,OAAA,MAAO,SAAS,CAAA,GAAA,CAAA;gBAErBI,mBAsBM,OAtBN,aAsBM;AAAA,mBArBJL,UAAA,IAAA,GAAAD,mBAoBMG,2BAnBqB,SAAA,MAAS,SAAS,KAAA,CAAA,GAAA,CAAnC,MAAM,UAAK;wCADrBH,mBAoBM,OAAA;AAAA,sBAlBH,KAAK;AAAA,sBACN,OAAM;AAAA,oBAAA;sBAENM,mBAME,SAAA;AAAA,wBALA,MAAK;AAAA,wBACJ,OAAO;AAAA,wBACP,UAAU,QAAA;AAAA,wBACV,SAAK,CAAA,WAAE,gBAAgB,WAAW,OAAQ,OAAO,OAA4B,KAAK;AAAA,wBACnF,OAAM;AAAA,sBAAA;sBAERA,mBAOS,UAAA;AAAA,wBANP,MAAK;AAAA,wBACJ,SAAK,CAAA,WAAE,gBAAgB,WAAW,KAAK;AAAA,wBACvC,UAAU,QAAA;AAAA,wBACX,OAAM;AAAA,sBAAA,GACP,YAED,GAAA,WAAA;AAAA,oBAAA;;;gBAGJA,mBAOS,UAAA;AAAA,kBANP,MAAK;AAAA,kBACJ,SAAK,CAAA,WAAE,aAAa,SAAS;AAAA,kBAC7B,UAAU,QAAA;AAAA,kBACX,OAAM;AAAA,gBAAA,GACP,gBAED,GAAA,WAAA;AAAA,cAAA,MAIc,UAAU,SAAS,MAAA,YAAkB,UAAU,SAAS,MAAA,UAAxEL,UAAA,GAAAD,mBAqBM,OArBN,aAqBM;AAAA,gBApBJM,mBAOM,OAAA,MAAA;AAAA,kBANJA,mBAEK,MAFL,aAEKJ,gBADA,cAAc,SAAS,CAAA,GAAA,CAAA;AAAA,kBAEnB,oBAAoB,SAAS,KAAtCD,UAAA,GAAAD,mBAEI,KAFJ,aAEIE,gBADC,oBAAoB,SAAS,CAAA,GAAA,CAAA;;gBAGpCI,mBAWM,OAXN,aAWM;AAAA,mBATJL,UAAA,IAAA,GAAAD,mBAQMG,2BAP2B,YAAY,YAAU,CAA7C,WAAW,YAAO;wCAD5BH,mBAQM,OAAA,EANH,KAAK,WAAO;AAAA,sBAGbM,mBAEI,KAFJ,aAAiC,oBACjBJ,gBAAG,OAAO,IAAG,aAAQA,gBAAG,UAAU,IAAI,IAAG,MACzD,CAAA;AAAA,oBAAA;;;;;;;QAQVI,mBAUM,OAVN,aAUM;AAAA,UATJC,WAQO,4BARP,MAQO;AAAA,YAPLC,YAMWH,MAAA,QAAA,GAAA;AAAA,cALT,MAAK;AAAA,cACL,OAAM;AAAA,cACL,SAAS,QAAA;AAAA,YAAA;+BACX,MAED,CAAA,GAAA,OAAA,CAAA,MAAA,OAAA,CAAA,IAAA;AAAA,gCAFC,YAED,EAAA;AAAA,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3kBR,UAAM,QAAQ;AAcd,UAAM,OAAO;AAOb,UAAM,iBAAiB,IAAoB;AAAA,MACzC,QAAM,WAAM,eAAN,mBAAkB,SAAQ;AAAA,MAChC,MAAI,WAAM,eAAN,mBAAkB,QAAM,oBAAI,KAAA,GAAO,YAAA,EAAc,MAAM,GAAG,EAAE;AAAA,IAAA,CACjE;AAGD,UAAM,MAAM,MAAM,YAAY,CAAC,aAAa;AAC1C,UAAI,UAAU;AACZ,uBAAe,QAAQ;AAAA,UACrB,MAAM,SAAS,QAAQ;AAAA,UACvB,IAAI,SAAS,OAAM,oBAAI,KAAA,GAAO,YAAA,EAAc,MAAM,GAAG,EAAE;AAAA,QAAA;AAAA,MAE3D;AAAA,IACF,GAAG,EAAE,MAAM,MAAM;AAGjB,aAAS,aAAa,OAAmC;AACvD,WAAK,qBAAqB,KAAK;AAC/B,WAAK,UAAU,KAAK;AACpB,WAAK,UAAU,KAAK;AAAA,IACtB;AAGA,aAAS,QAAQ;AACf,YAAM,aAA6B;AAAA,QACjC,MAAM;AAAA,QACN,yBAAQ,KAAA,GAAO,cAAc,MAAM,GAAG,EAAE;AAAA,MAAA;AAE1C,qBAAe,QAAQ;AACvB,WAAK,qBAAqB,UAAU;AAAA,IACtC;AAEA,aAAS,WAAW;AAClB,aAAO,eAAe;AAAA,IACxB;AAEA,aAAS,SAAS,OAAuB;AACvC,qBAAe,QAAQ;AACvB,WAAK,qBAAqB,KAAK;AAAA,IACjC;AAEA,aAAa;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;;0BA3GCD,YAWEC,MAAA,WAAA,GAAA;AAAA,QAVC,IAAI,QAAA;AAAA,QACJ,SAAS,QAAA;AAAA,QACT,UAAU,QAAA;AAAA,QACV,QAAQ,eAAA;AAAA,QACR,OAAO,QAAA;AAAA,QACP,OAAO,QAAA;AAAA,QACP,UAAU,QAAA;AAAA,QACV,OAAO,QAAA;AAAA,QACP,aAAa,QAAA;AAAA,QACb,4BAA0B;AAAA,MAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js","sources":["../src/domain/BrandSelector.vue","../src/domain/BrandCard.vue","../src/domain/UserAvatar.vue","../src/domain/ProductBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiCard } from '@hotelinking/ui';\n\ninterface Brand {\n id: string;\n name: string;\n logo?: string;\n type?: string;\n}\n\ninterface Props {\n modelValue?: Brand | null;\n brands?: Brand[];\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: null,\n brands: () => [],\n loading: false\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: Brand | null];\n 'change': [value: Brand | null];\n}>();\n\nfunction selectBrand(data: any) {\n const brand = props.brands.find(b => b.id === data.id);\n if (brand) {\n emit('update:modelValue', brand);\n emit('change', brand);\n }\n}\n\n// Expose methods for parent components\ndefineExpose({\n getSelected: () => props.modelValue,\n clearSelection: () => {\n emit('update:modelValue', null);\n emit('change', null);\n }\n});\n</script>\n\n<template>\n <div class=\"w-full\">\n <div v-if=\"loading\" class=\"text-center py-4 text-gray-500\">\n Loading brands...\n </div>\n <div v-else class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n <uiCard\n v-for=\"brand in brands\"\n :key=\"brand.id\"\n :id=\"brand.id\"\n :name=\"brand.name\"\n :type=\"brand.type || 'Brand'\"\n :logo=\"brand.logo || ''\"\n :loading=\"false\"\n @card-selected=\"selectBrand\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiCard } from '@hotelinking/ui';\n\ninterface Brand {\n id: string;\n name: string;\n logo?: string;\n status?: 'active' | 'inactive' | 'maintenance' | 'suspended';\n timezone?: string;\n}\n\ninterface Props {\n brand: Brand;\n showStatus?: boolean;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n showStatus: true,\n loading: false\n});\n\nconst emit = defineEmits<{\n 'click': [brand: Brand];\n}>();\n\n// Convert status to tag format\nconst tags = computed(() => {\n if (!props.showStatus || !props.brand.status) return [];\n \n const statusMap = {\n active: { name: 'Active', color: 'green' as const },\n inactive: { name: 'Inactive', color: 'gray' as const },\n maintenance: { name: 'Maintenance', color: 'yellow' as const },\n suspended: { name: 'Suspended', color: 'red' as const }\n };\n \n return [statusMap[props.brand.status]];\n});\n\n// Handle card selection\nfunction handleCardSelected(data: any) {\n emit('click', props.brand);\n}\n\n// Expose methods for parent components\ndefineExpose({\n getBrand: () => props.brand\n});\n</script>\n\n<template>\n <uiCard\n :id=\"brand.id\"\n :name=\"brand.name\"\n :type=\"brand.timezone || 'Brand'\"\n :logo=\"brand.logo || ''\"\n :tags=\"tags\"\n :loading=\"loading\"\n @card-selected=\"handleCardSelected\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface User {\n username?: string;\n email?: string;\n avatar?: string;\n name?: string;\n}\n\ninterface Props {\n user: User;\n size?: 'small' | 'medium' | 'large';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'medium'\n});\n\nconst initials = computed(() => {\n const name = props.user.name || props.user.username || props.user.email || '';\n const parts = name.split(' ');\n if (parts.length >= 2) {\n return `${parts[0][0]}${parts[1][0]}`.toUpperCase();\n }\n return name.substring(0, 2).toUpperCase();\n});\n\nconst sizeClasses = computed(() => {\n const sizes = {\n small: 'w-8 h-8 text-xs',\n medium: 'w-10 h-10 text-sm',\n large: 'w-14 h-14 text-lg'\n };\n return sizes[props.size];\n});\n\n// Expose methods for parent components\ndefineExpose({\n getInitials: () => initials.value,\n getUser: () => props.user\n});\n</script>\n\n<template>\n <div\n class=\"flex items-center justify-center rounded-full overflow-hidden bg-blue-500 text-white font-medium\"\n :class=\"sizeClasses\"\n >\n <img\n v-if=\"user.avatar\"\n :src=\"user.avatar\"\n :alt=\"user.username || user.email\"\n class=\"w-full h-full object-cover\"\n />\n <div v-else class=\"flex items-center justify-center w-full h-full\">\n {{ initials }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiTag } from '@hotelinking/ui';\n\ninterface Product {\n name: string;\n status?: 'enabled' | 'disabled' | 'pending';\n version?: string;\n}\n\ninterface Props {\n product: Product;\n showVersion?: boolean;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n showVersion: false,\n loading: false\n});\n\nconst statusColor = computed(() => {\n switch (props.product.status) {\n case 'enabled': return 'green' as const;\n case 'disabled': return 'gray' as const;\n case 'pending': return 'yellow' as const;\n default: return 'gray' as const;\n }\n});\n\nconst badgeText = computed(() => {\n let text = props.product.name;\n if (props.showVersion && props.product.version) {\n text += ` v${props.product.version}`;\n }\n return text;\n});\n</script>\n\n<template>\n <uiTag\n :loading=\"loading\"\n :color=\"statusColor\"\n :text=\"badgeText\"\n size=\"medium\"\n />\n</template>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_Fragment","_renderList","_createBlock","_unref","_normalizeClass","_toDisplayString"],"mappings":"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"}
1
+ {"version":3,"file":"ProductBadge.vue_vue_type_script_setup_true_lang-Cmr2f4Cy.js","sources":["../src/domain/BrandSelector/BrandSelector.vue","../src/domain/BrandCard/BrandCard.vue","../src/domain/UserAvatar/UserAvatar.vue","../src/domain/ProductBadge/ProductBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiCard } from '@hotelinking/ui';\n\ninterface Brand {\n id: string;\n name: string;\n logo?: string;\n type?: string;\n}\n\ninterface Props {\n modelValue?: Brand | null;\n brands?: Brand[];\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n modelValue: null,\n brands: () => [],\n loading: false\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: Brand | null];\n 'change': [value: Brand | null];\n}>();\n\nfunction selectBrand(data: any) {\n const brand = props.brands.find(b => b.id === data.id);\n if (brand) {\n emit('update:modelValue', brand);\n emit('change', brand);\n }\n}\n\n// Expose methods for parent components\ndefineExpose({\n getSelected: () => props.modelValue,\n clearSelection: () => {\n emit('update:modelValue', null);\n emit('change', null);\n }\n});\n</script>\n\n<template>\n <div class=\"w-full\">\n <div v-if=\"loading\" class=\"text-center py-4 text-gray-500\">\n Loading brands...\n </div>\n <div v-else class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n <uiCard\n v-for=\"brand in brands\"\n :key=\"brand.id\"\n :id=\"brand.id\"\n :name=\"brand.name\"\n :type=\"brand.type || 'Brand'\"\n :logo=\"brand.logo || ''\"\n :loading=\"false\"\n @card-selected=\"selectBrand\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiCard } from '@hotelinking/ui';\n\ninterface Brand {\n id: string;\n name: string;\n logo?: string;\n status?: 'active' | 'inactive' | 'maintenance' | 'suspended';\n timezone?: string;\n}\n\ninterface Props {\n brand: Brand;\n showStatus?: boolean;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n showStatus: true,\n loading: false\n});\n\nconst emit = defineEmits<{\n 'click': [brand: Brand];\n}>();\n\n// Convert status to tag format\nconst tags = computed(() => {\n if (!props.showStatus || !props.brand.status) return [];\n \n const statusMap = {\n active: { name: 'Active', color: 'green' as const },\n inactive: { name: 'Inactive', color: 'gray' as const },\n maintenance: { name: 'Maintenance', color: 'yellow' as const },\n suspended: { name: 'Suspended', color: 'red' as const }\n };\n \n return [statusMap[props.brand.status]];\n});\n\n// Handle card selection\nfunction handleCardSelected(data: any) {\n emit('click', props.brand);\n}\n\n// Expose methods for parent components\ndefineExpose({\n getBrand: () => props.brand\n});\n</script>\n\n<template>\n <uiCard\n :id=\"brand.id\"\n :name=\"brand.name\"\n :type=\"brand.timezone || 'Brand'\"\n :logo=\"brand.logo || ''\"\n :tags=\"tags\"\n :loading=\"loading\"\n @card-selected=\"handleCardSelected\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\ninterface User {\n username?: string;\n email?: string;\n avatar?: string;\n name?: string;\n}\n\ninterface Props {\n user: User;\n size?: 'small' | 'medium' | 'large';\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: 'medium'\n});\n\nconst initials = computed(() => {\n const name = props.user.name || props.user.username || props.user.email || '';\n const parts = name.split(' ');\n if (parts.length >= 2) {\n return `${parts[0][0]}${parts[1][0]}`.toUpperCase();\n }\n return name.substring(0, 2).toUpperCase();\n});\n\nconst sizeClasses = computed(() => {\n const sizes = {\n small: 'w-8 h-8 text-xs',\n medium: 'w-10 h-10 text-sm',\n large: 'w-14 h-14 text-lg'\n };\n return sizes[props.size];\n});\n\n// Expose methods for parent components\ndefineExpose({\n getInitials: () => initials.value,\n getUser: () => props.user\n});\n</script>\n\n<template>\n <div\n class=\"flex items-center justify-center rounded-full overflow-hidden bg-blue-500 text-white font-medium\"\n :class=\"sizeClasses\"\n >\n <img\n v-if=\"user.avatar\"\n :src=\"user.avatar\"\n :alt=\"user.username || user.email\"\n class=\"w-full h-full object-cover\"\n />\n <div v-else class=\"flex items-center justify-center w-full h-full\">\n {{ initials }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { uiTag } from '@hotelinking/ui';\n\ninterface Product {\n name: string;\n status?: 'enabled' | 'disabled' | 'pending';\n version?: string;\n}\n\ninterface Props {\n product: Product;\n showVersion?: boolean;\n loading?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n showVersion: false,\n loading: false\n});\n\nconst statusColor = computed(() => {\n switch (props.product.status) {\n case 'enabled': return 'green' as const;\n case 'disabled': return 'gray' as const;\n case 'pending': return 'yellow' as const;\n default: return 'gray' as const;\n }\n});\n\nconst badgeText = computed(() => {\n let text = props.product.name;\n if (props.showVersion && props.product.version) {\n text += ` v${props.product.version}`;\n }\n return text;\n});\n</script>\n\n<template>\n <uiTag\n :loading=\"loading\"\n :color=\"statusColor\"\n :text=\"badgeText\"\n size=\"medium\"\n />\n</template>\n"],"names":["_openBlock","_createElementBlock","_hoisted_1","_hoisted_2","_Fragment","_renderList","_createBlock","_unref","_normalizeClass","_toDisplayString"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
1
 
2
- .table-component[data-v-80c477af] {
2
+ .table-component[data-v-af67d07d] {
3
3
  width: 100%;
4
4
  }
5
5
 
6
- .tabs-wrapper[data-v-c776bc53] {
6
+ .tabs-wrapper[data-v-ece16231] {
7
7
  width: 100%;
8
8
  }
9
- .tabs-content[data-v-c776bc53] {
9
+ .tabs-content[data-v-ece16231] {
10
10
  margin-top: 1rem;
11
11
  }
12
12
 
13
- .breadcrumbs-wrapper[data-v-3137d38d] {
13
+ .breadcrumbs-wrapper[data-v-4a163049] {
14
14
  width: 100%;
15
15
  }
@@ -1,34 +1,35 @@
1
1
  import { u } from "../useTable-DutR1gkg.js";
2
- import { k, $, P, p, n, q, v, j, s, o, w, r, y, b, z, c, t, g, f, i, x, u as u2, d, e, m, a, h, l } from "../useAdminPage-GhgXp0x8.js";
2
+ import { l, $, P, q, o, r, w, k, s, p, x, t, z, b, A, c, v, h, g, j, d, y, u as u2, e, f, n, a, i, m } from "../useAdminPage-AgWRvw6o.js";
3
3
  export {
4
- k as $currentBrand,
4
+ l as $currentBrand,
5
5
  $ as $user,
6
6
  P as PAGE_CONTEXT_KEY,
7
- p as averageStat,
8
- n as countStat,
9
- q as percentageStat,
10
- v as resetGlobalConfirmation,
11
- j as setCurrentBrand,
7
+ q as averageStat,
8
+ o as countStat,
9
+ r as percentageStat,
10
+ w as resetGlobalConfirmation,
11
+ k as setCurrentBrand,
12
12
  s as setUser,
13
- o as sumStat,
14
- w as useAdminPage,
15
- r as useConfirmation,
16
- y as useDetailPage,
13
+ p as sumStat,
14
+ x as useAdminPage,
15
+ t as useConfirmation,
16
+ z as useDetailPage,
17
17
  b as useForm,
18
- z as useFormPage,
18
+ A as useFormPage,
19
19
  c as useFormValidation,
20
- t as useGlobalConfirmation,
21
- g as useHasAccessToAccount,
22
- f as useHasAccessToBrand,
23
- i as useHasRole,
24
- x as useListPage,
20
+ v as useGlobalConfirmation,
21
+ h as useHasAccessToAccount,
22
+ g as useHasAccessToBrand,
23
+ j as useHasRole,
24
+ d as useJsonForm,
25
+ y as useListPage,
25
26
  u2 as useModal,
26
- d as useNotifications,
27
- e as usePageContext,
28
- m as useStats,
27
+ e as useNotifications,
28
+ f as usePageContext,
29
+ n as useStats,
29
30
  u as useTable,
30
31
  a as useTabs,
31
- h as useUserRoles,
32
- l as useWizard
32
+ i as useUserRoles,
33
+ m as useWizard
33
34
  };
34
35
  //# sourceMappingURL=index.js.map
@@ -1,18 +1,18 @@
1
- import { b, _, c, a, T, k, d, i, e, h, f, g, s, j } from "../filterHelpers-DgRyoYSa.js";
1
+ import { j, _, k, i, T, h, c, d, a, b, f, g, s, e } from "../filterHelpers-DpHSlTuh.js";
2
2
  export {
3
- b as Chart,
3
+ j as Chart,
4
4
  _ as DataList,
5
- c as DataTable,
6
- a as SearchableSelect,
5
+ k as DataTable,
6
+ i as SearchableSelect,
7
7
  T as Table,
8
- k as booleanOptions,
9
- d as columns,
10
- i as createFilterGroup,
11
- e as createStatusColorFn,
12
- h as filterPresets,
8
+ h as booleanOptions,
9
+ c as columns,
10
+ d as createFilterGroup,
11
+ a as createStatusColorFn,
12
+ b as filterPresets,
13
13
  f as filters,
14
14
  g as getStatusColor,
15
15
  s as statusColors,
16
- j as statusOptions
16
+ e as statusOptions
17
17
  };
18
18
  //# sourceMappingURL=index.js.map
@@ -175,7 +175,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
175
175
  };
176
176
  }
177
177
  });
178
- const Table = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-80c477af"]]);
178
+ const Table = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-af67d07d"]]);
179
179
  const _hoisted_1 = { class: "w-full" };
180
180
  const _hoisted_2 = {
181
181
  key: 0,
@@ -1370,17 +1370,17 @@ const filterPresets = {
1370
1370
  export {
1371
1371
  Table as T,
1372
1372
  _sfc_main$3 as _,
1373
- _sfc_main$2 as a,
1374
- _sfc_main$1 as b,
1375
- _sfc_main as c,
1376
- columns as d,
1377
- createStatusColorFn as e,
1373
+ createStatusColorFn as a,
1374
+ filterPresets as b,
1375
+ columns as c,
1376
+ createFilterGroup as d,
1377
+ statusOptions as e,
1378
1378
  filters as f,
1379
1379
  getStatusColor as g,
1380
- filterPresets as h,
1381
- createFilterGroup as i,
1382
- statusOptions as j,
1383
- booleanOptions as k,
1380
+ booleanOptions as h,
1381
+ _sfc_main$2 as i,
1382
+ _sfc_main$1 as j,
1383
+ _sfc_main as k,
1384
1384
  statusColors as s
1385
1385
  };
1386
- //# sourceMappingURL=filterHelpers-DgRyoYSa.js.map
1386
+ //# sourceMappingURL=filterHelpers-DpHSlTuh.js.map