From 0c1e54fc3dbcb6f3223b3b69f1fa902d959f56f3 Mon Sep 17 00:00:00 2001 From: faiztyanirh Date: Sun, 1 Feb 2026 21:47:55 +0700 Subject: [PATCH] initial commit --- .gitignore | 23 + .npmrc | 1 + .prettierignore | 9 + .prettierrc | 15 + README.md | 38 + components.json | 16 + eslint.config.js | 26 + jsconfig.json | 13 + package-lock.json | 3742 +++++++++++++++++ package.json | 45 + src/app.css | 121 + src/app.html | 11 + src/lib/api/api-client.js | 110 + src/lib/assets/favicon.svg | 1 + src/lib/components/app-sidebar.svelte | 166 + .../composable/use-form-option.svelte.js | 99 + .../composable/use-form-state.svelte.js | 15 + .../composable/use-form-validation.svelte.js | 31 + .../components/composable/use-form.svelte.js | 37 + .../composable/use-patient-form.svelte.js | 102 + .../composable/useMasterDetail.svelte.js | 136 + .../composable/useResponsive.svelte.js | 20 + .../components/composable/useSearch.svelte.js | 41 + src/lib/components/nav-dictionary.svelte | 61 + src/lib/components/nav-main.svelte | 115 + src/lib/components/nav-user.svelte | 87 + src/lib/components/patient/api/patient-api.js | 21 + .../patient/config/patient-config.js | 145 + .../patient/config/patient-form-config.js | 311 ++ .../patient/modal/custodian-modal.svelte | 157 + .../patient/modal/linkto-modal.svelte | 286 ++ .../patient/page/create-page copy.svelte | 403 ++ .../patient/page/create-page.svelte | 74 + .../components/patient/page/edit-page.svelte | 523 +++ .../patient/page/master-page.svelte | 63 + .../components/patient/page/view-page.svelte | 123 + .../reusable/form-page-container.svelte | 82 + .../reusable/patient-form-renderer.svelte | 334 ++ src/lib/components/patient/table/colums.js | 23 + .../reusable-calendar-timepicker.svelte | 196 + .../reusable/reusable-calendar.svelte | 71 + .../reusable/reusable-data-table.svelte | 187 + .../components/reusable/reusable-empty.svelte | 19 + .../reusable/reusable-search-param.svelte | 53 + .../reusable/reusable-upload.svelte | 277 ++ .../components/topbar/topbar-action.svelte | 51 + .../components/topbar/topbar-wrapper.svelte | 19 + .../ui/avatar/avatar-fallback.svelte | 17 + .../components/ui/avatar/avatar-image.svelte | 17 + src/lib/components/ui/avatar/avatar.svelte | 19 + src/lib/components/ui/avatar/index.js | 13 + .../ui/breadcrumb/breadcrumb-ellipsis.svelte | 22 + .../ui/breadcrumb/breadcrumb-item.svelte | 19 + .../ui/breadcrumb/breadcrumb-link.svelte | 27 + .../ui/breadcrumb/breadcrumb-list.svelte | 22 + .../ui/breadcrumb/breadcrumb-page.svelte | 22 + .../ui/breadcrumb/breadcrumb-separator.svelte | 25 + .../ui/breadcrumb/breadcrumb.svelte | 18 + src/lib/components/ui/breadcrumb/index.js | 25 + src/lib/components/ui/button/button.svelte | 73 + src/lib/components/ui/button/index.js | 13 + .../ui/calendar/calendar-caption.svelte | 64 + .../ui/calendar/calendar-cell.svelte | 19 + .../ui/calendar/calendar-day.svelte | 35 + .../ui/calendar/calendar-grid-body.svelte | 12 + .../ui/calendar/calendar-grid-head.svelte | 12 + .../ui/calendar/calendar-grid-row.svelte | 12 + .../ui/calendar/calendar-grid.svelte | 16 + .../ui/calendar/calendar-head-cell.svelte | 19 + .../ui/calendar/calendar-header.svelte | 19 + .../ui/calendar/calendar-heading.svelte | 16 + .../ui/calendar/calendar-month-select.svelte | 44 + .../ui/calendar/calendar-month.svelte | 13 + .../ui/calendar/calendar-months.svelte | 18 + .../ui/calendar/calendar-nav.svelte | 17 + .../ui/calendar/calendar-next-button.svelte | 29 + .../ui/calendar/calendar-prev-button.svelte | 29 + .../ui/calendar/calendar-year-select.svelte | 43 + .../components/ui/calendar/calendar.svelte | 104 + src/lib/components/ui/calendar/index.js | 40 + src/lib/components/ui/card/card-action.svelte | 18 + .../components/ui/card/card-content.svelte | 14 + .../ui/card/card-description.svelte | 19 + src/lib/components/ui/card/card-footer.svelte | 18 + src/lib/components/ui/card/card-header.svelte | 21 + src/lib/components/ui/card/card-title.svelte | 19 + src/lib/components/ui/card/card.svelte | 22 + src/lib/components/ui/card/index.js | 25 + .../components/ui/checkbox/checkbox.svelte | 36 + src/lib/components/ui/checkbox/index.js | 6 + .../ui/collapsible/collapsible-content.svelte | 7 + .../ui/collapsible/collapsible-trigger.svelte | 7 + .../ui/collapsible/collapsible.svelte | 11 + src/lib/components/ui/collapsible/index.js | 13 + .../ui/data-table/data-table.svelte.js | 134 + .../ui/data-table/flex-render.svelte | 24 + src/lib/components/ui/data-table/index.js | 3 + .../ui/data-table/render-helpers.js | 107 + .../components/ui/dialog/dialog-close.svelte | 7 + .../ui/dialog/dialog-content.svelte | 38 + .../ui/dialog/dialog-description.svelte | 17 + .../components/ui/dialog/dialog-footer.svelte | 18 + .../components/ui/dialog/dialog-header.svelte | 19 + .../ui/dialog/dialog-overlay.svelte | 20 + .../components/ui/dialog/dialog-portal.svelte | 7 + .../components/ui/dialog/dialog-title.svelte | 17 + .../ui/dialog/dialog-trigger.svelte | 7 + src/lib/components/ui/dialog/dialog.svelte | 7 + src/lib/components/ui/dialog/index.js | 34 + .../dropdown-menu-checkbox-group.svelte | 16 + .../dropdown-menu-checkbox-item.svelte | 39 + .../dropdown-menu-content.svelte | 25 + .../dropdown-menu-group-heading.svelte | 18 + .../dropdown-menu/dropdown-menu-group.svelte | 7 + .../dropdown-menu/dropdown-menu-item.svelte | 24 + .../dropdown-menu/dropdown-menu-label.svelte | 20 + .../dropdown-menu/dropdown-menu-portal.svelte | 7 + .../dropdown-menu-radio-group.svelte | 16 + .../dropdown-menu-radio-item.svelte | 33 + .../dropdown-menu-separator.svelte | 17 + .../dropdown-menu-shortcut.svelte | 19 + .../dropdown-menu-sub-content.svelte | 20 + .../dropdown-menu-sub-trigger.svelte | 27 + .../ui/dropdown-menu/dropdown-menu-sub.svelte | 7 + .../dropdown-menu-trigger.svelte | 7 + .../ui/dropdown-menu/dropdown-menu.svelte | 7 + src/lib/components/ui/dropdown-menu/index.js | 54 + .../components/ui/empty/empty-content.svelte | 21 + .../ui/empty/empty-description.svelte | 21 + .../components/ui/empty/empty-header.svelte | 18 + .../components/ui/empty/empty-media.svelte | 37 + .../components/ui/empty/empty-title.svelte | 18 + src/lib/components/ui/empty/empty.svelte | 21 + src/lib/components/ui/empty/index.js | 22 + src/lib/components/ui/input/index.js | 7 + src/lib/components/ui/input/input.svelte | 44 + src/lib/components/ui/label/index.js | 7 + src/lib/components/ui/label/label.svelte | 20 + src/lib/components/ui/popover/index.js | 19 + .../ui/popover/popover-close.svelte | 7 + .../ui/popover/popover-content.svelte | 27 + .../ui/popover/popover-portal.svelte | 7 + .../ui/popover/popover-trigger.svelte | 17 + src/lib/components/ui/popover/popover.svelte | 7 + src/lib/components/ui/radio-group/index.js | 10 + .../ui/radio-group/radio-group-item.svelte | 31 + .../ui/radio-group/radio-group.svelte | 19 + src/lib/components/ui/select/index.js | 37 + .../ui/select/select-content.svelte | 40 + .../ui/select/select-group-heading.svelte | 19 + .../components/ui/select/select-group.svelte | 7 + .../components/ui/select/select-item.svelte | 38 + .../components/ui/select/select-label.svelte | 18 + .../components/ui/select/select-portal.svelte | 7 + .../select/select-scroll-down-button.svelte | 20 + .../ui/select/select-scroll-up-button.svelte | 20 + .../ui/select/select-separator.svelte | 17 + .../ui/select/select-trigger.svelte | 27 + src/lib/components/ui/select/select.svelte | 11 + src/lib/components/ui/separator/index.js | 7 + .../components/ui/separator/separator.svelte | 21 + src/lib/components/ui/sheet/index.js | 34 + .../components/ui/sheet/sheet-close.svelte | 7 + .../components/ui/sheet/sheet-content.svelte | 51 + .../ui/sheet/sheet-description.svelte | 17 + .../components/ui/sheet/sheet-footer.svelte | 18 + .../components/ui/sheet/sheet-header.svelte | 19 + .../components/ui/sheet/sheet-overlay.svelte | 20 + .../components/ui/sheet/sheet-portal.svelte | 7 + .../components/ui/sheet/sheet-title.svelte | 17 + .../components/ui/sheet/sheet-trigger.svelte | 7 + src/lib/components/ui/sheet/sheet.svelte | 7 + src/lib/components/ui/sidebar/constants.js | 6 + .../components/ui/sidebar/context.svelte.js | 63 + src/lib/components/ui/sidebar/index.js | 75 + .../ui/sidebar/sidebar-content.svelte | 23 + .../ui/sidebar/sidebar-footer.svelte | 20 + .../ui/sidebar/sidebar-group-action.svelte | 31 + .../ui/sidebar/sidebar-group-content.svelte | 19 + .../ui/sidebar/sidebar-group-label.svelte | 29 + .../ui/sidebar/sidebar-group.svelte | 20 + .../ui/sidebar/sidebar-header.svelte | 20 + .../ui/sidebar/sidebar-input.svelte | 20 + .../ui/sidebar/sidebar-inset.svelte | 22 + .../ui/sidebar/sidebar-menu-action.svelte | 37 + .../ui/sidebar/sidebar-menu-badge.svelte | 27 + .../ui/sidebar/sidebar-menu-button.svelte | 90 + .../ui/sidebar/sidebar-menu-item.svelte | 19 + .../ui/sidebar/sidebar-menu-skeleton.svelte | 32 + .../ui/sidebar/sidebar-menu-sub-button.svelte | 36 + .../ui/sidebar/sidebar-menu-sub-item.svelte | 19 + .../ui/sidebar/sidebar-menu-sub.svelte | 23 + .../components/ui/sidebar/sidebar-menu.svelte | 19 + .../ui/sidebar/sidebar-provider.svelte | 49 + .../components/ui/sidebar/sidebar-rail.svelte | 35 + .../ui/sidebar/sidebar-separator.svelte | 17 + .../ui/sidebar/sidebar-trigger.svelte | 32 + src/lib/components/ui/sidebar/sidebar.svelte | 99 + src/lib/components/ui/skeleton/index.js | 7 + .../components/ui/skeleton/skeleton.svelte | 15 + src/lib/components/ui/spinner/index.js | 1 + src/lib/components/ui/spinner/spinner.svelte | 12 + src/lib/components/ui/table/index.js | 28 + src/lib/components/ui/table/table-body.svelte | 18 + .../components/ui/table/table-caption.svelte | 18 + src/lib/components/ui/table/table-cell.svelte | 21 + .../components/ui/table/table-footer.svelte | 18 + src/lib/components/ui/table/table-head.svelte | 21 + .../components/ui/table/table-header.svelte | 18 + src/lib/components/ui/table/table-row.svelte | 21 + src/lib/components/ui/table/table.svelte | 21 + src/lib/components/ui/tooltip/index.js | 19 + .../ui/tooltip/tooltip-content.svelte | 46 + .../ui/tooltip/tooltip-portal.svelte | 7 + .../ui/tooltip/tooltip-provider.svelte | 7 + .../ui/tooltip/tooltip-trigger.svelte | 7 + src/lib/components/ui/tooltip/tooltip.svelte | 7 + src/lib/config/api.js | 29 + src/lib/hooks/is-mobile.svelte.js | 9 + src/lib/index.js | 1 + src/lib/utils.js | 8 + src/lib/utils/cleanEmptyStrings.js | 11 + src/lib/utils/formatUTCDate.js | 16 + src/lib/utils/getUrl.js | 5 + src/routes/+layout.server.js | 17 + src/routes/+layout.svelte | 55 + src/routes/+page.svelte | 2 + src/routes/api/preview/[...path]/+server.js | 30 + src/routes/api/upload/+server.js | 149 + src/routes/patient/+page.svelte | 34 + src/routes/sidebar-07/+page.svelte | 39 + static/robots.txt | 3 + svelte.config.js | 13 + vite.config.js | 7 + 234 files changed, 12945 insertions(+) create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 components.json create mode 100644 eslint.config.js create mode 100644 jsconfig.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/app.css create mode 100644 src/app.html create mode 100644 src/lib/api/api-client.js create mode 100644 src/lib/assets/favicon.svg create mode 100644 src/lib/components/app-sidebar.svelte create mode 100644 src/lib/components/composable/use-form-option.svelte.js create mode 100644 src/lib/components/composable/use-form-state.svelte.js create mode 100644 src/lib/components/composable/use-form-validation.svelte.js create mode 100644 src/lib/components/composable/use-form.svelte.js create mode 100644 src/lib/components/composable/use-patient-form.svelte.js create mode 100644 src/lib/components/composable/useMasterDetail.svelte.js create mode 100644 src/lib/components/composable/useResponsive.svelte.js create mode 100644 src/lib/components/composable/useSearch.svelte.js create mode 100644 src/lib/components/nav-dictionary.svelte create mode 100644 src/lib/components/nav-main.svelte create mode 100644 src/lib/components/nav-user.svelte create mode 100644 src/lib/components/patient/api/patient-api.js create mode 100644 src/lib/components/patient/config/patient-config.js create mode 100644 src/lib/components/patient/config/patient-form-config.js create mode 100644 src/lib/components/patient/modal/custodian-modal.svelte create mode 100644 src/lib/components/patient/modal/linkto-modal.svelte create mode 100644 src/lib/components/patient/page/create-page copy.svelte create mode 100644 src/lib/components/patient/page/create-page.svelte create mode 100644 src/lib/components/patient/page/edit-page.svelte create mode 100644 src/lib/components/patient/page/master-page.svelte create mode 100644 src/lib/components/patient/page/view-page.svelte create mode 100644 src/lib/components/patient/reusable/form-page-container.svelte create mode 100644 src/lib/components/patient/reusable/patient-form-renderer.svelte create mode 100644 src/lib/components/patient/table/colums.js create mode 100644 src/lib/components/reusable/reusable-calendar-timepicker.svelte create mode 100644 src/lib/components/reusable/reusable-calendar.svelte create mode 100644 src/lib/components/reusable/reusable-data-table.svelte create mode 100644 src/lib/components/reusable/reusable-empty.svelte create mode 100644 src/lib/components/reusable/reusable-search-param.svelte create mode 100644 src/lib/components/reusable/reusable-upload.svelte create mode 100644 src/lib/components/topbar/topbar-action.svelte create mode 100644 src/lib/components/topbar/topbar-wrapper.svelte create mode 100644 src/lib/components/ui/avatar/avatar-fallback.svelte create mode 100644 src/lib/components/ui/avatar/avatar-image.svelte create mode 100644 src/lib/components/ui/avatar/avatar.svelte create mode 100644 src/lib/components/ui/avatar/index.js create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-item.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-link.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-list.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-page.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb.svelte create mode 100644 src/lib/components/ui/breadcrumb/index.js create mode 100644 src/lib/components/ui/button/button.svelte create mode 100644 src/lib/components/ui/button/index.js create mode 100644 src/lib/components/ui/calendar/calendar-caption.svelte create mode 100644 src/lib/components/ui/calendar/calendar-cell.svelte create mode 100644 src/lib/components/ui/calendar/calendar-day.svelte create mode 100644 src/lib/components/ui/calendar/calendar-grid-body.svelte create mode 100644 src/lib/components/ui/calendar/calendar-grid-head.svelte create mode 100644 src/lib/components/ui/calendar/calendar-grid-row.svelte create mode 100644 src/lib/components/ui/calendar/calendar-grid.svelte create mode 100644 src/lib/components/ui/calendar/calendar-head-cell.svelte create mode 100644 src/lib/components/ui/calendar/calendar-header.svelte create mode 100644 src/lib/components/ui/calendar/calendar-heading.svelte create mode 100644 src/lib/components/ui/calendar/calendar-month-select.svelte create mode 100644 src/lib/components/ui/calendar/calendar-month.svelte create mode 100644 src/lib/components/ui/calendar/calendar-months.svelte create mode 100644 src/lib/components/ui/calendar/calendar-nav.svelte create mode 100644 src/lib/components/ui/calendar/calendar-next-button.svelte create mode 100644 src/lib/components/ui/calendar/calendar-prev-button.svelte create mode 100644 src/lib/components/ui/calendar/calendar-year-select.svelte create mode 100644 src/lib/components/ui/calendar/calendar.svelte create mode 100644 src/lib/components/ui/calendar/index.js create mode 100644 src/lib/components/ui/card/card-action.svelte create mode 100644 src/lib/components/ui/card/card-content.svelte create mode 100644 src/lib/components/ui/card/card-description.svelte create mode 100644 src/lib/components/ui/card/card-footer.svelte create mode 100644 src/lib/components/ui/card/card-header.svelte create mode 100644 src/lib/components/ui/card/card-title.svelte create mode 100644 src/lib/components/ui/card/card.svelte create mode 100644 src/lib/components/ui/card/index.js create mode 100644 src/lib/components/ui/checkbox/checkbox.svelte create mode 100644 src/lib/components/ui/checkbox/index.js create mode 100644 src/lib/components/ui/collapsible/collapsible-content.svelte create mode 100644 src/lib/components/ui/collapsible/collapsible-trigger.svelte create mode 100644 src/lib/components/ui/collapsible/collapsible.svelte create mode 100644 src/lib/components/ui/collapsible/index.js create mode 100644 src/lib/components/ui/data-table/data-table.svelte.js create mode 100644 src/lib/components/ui/data-table/flex-render.svelte create mode 100644 src/lib/components/ui/data-table/index.js create mode 100644 src/lib/components/ui/data-table/render-helpers.js create mode 100644 src/lib/components/ui/dialog/dialog-close.svelte create mode 100644 src/lib/components/ui/dialog/dialog-content.svelte create mode 100644 src/lib/components/ui/dialog/dialog-description.svelte create mode 100644 src/lib/components/ui/dialog/dialog-footer.svelte create mode 100644 src/lib/components/ui/dialog/dialog-header.svelte create mode 100644 src/lib/components/ui/dialog/dialog-overlay.svelte create mode 100644 src/lib/components/ui/dialog/dialog-portal.svelte create mode 100644 src/lib/components/ui/dialog/dialog-title.svelte create mode 100644 src/lib/components/ui/dialog/dialog-trigger.svelte create mode 100644 src/lib/components/ui/dialog/dialog.svelte create mode 100644 src/lib/components/ui/dialog/index.js create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.js create mode 100644 src/lib/components/ui/empty/empty-content.svelte create mode 100644 src/lib/components/ui/empty/empty-description.svelte create mode 100644 src/lib/components/ui/empty/empty-header.svelte create mode 100644 src/lib/components/ui/empty/empty-media.svelte create mode 100644 src/lib/components/ui/empty/empty-title.svelte create mode 100644 src/lib/components/ui/empty/empty.svelte create mode 100644 src/lib/components/ui/empty/index.js create mode 100644 src/lib/components/ui/input/index.js create mode 100644 src/lib/components/ui/input/input.svelte create mode 100644 src/lib/components/ui/label/index.js create mode 100644 src/lib/components/ui/label/label.svelte create mode 100644 src/lib/components/ui/popover/index.js create mode 100644 src/lib/components/ui/popover/popover-close.svelte create mode 100644 src/lib/components/ui/popover/popover-content.svelte create mode 100644 src/lib/components/ui/popover/popover-portal.svelte create mode 100644 src/lib/components/ui/popover/popover-trigger.svelte create mode 100644 src/lib/components/ui/popover/popover.svelte create mode 100644 src/lib/components/ui/radio-group/index.js create mode 100644 src/lib/components/ui/radio-group/radio-group-item.svelte create mode 100644 src/lib/components/ui/radio-group/radio-group.svelte create mode 100644 src/lib/components/ui/select/index.js create mode 100644 src/lib/components/ui/select/select-content.svelte create mode 100644 src/lib/components/ui/select/select-group-heading.svelte create mode 100644 src/lib/components/ui/select/select-group.svelte create mode 100644 src/lib/components/ui/select/select-item.svelte create mode 100644 src/lib/components/ui/select/select-label.svelte create mode 100644 src/lib/components/ui/select/select-portal.svelte create mode 100644 src/lib/components/ui/select/select-scroll-down-button.svelte create mode 100644 src/lib/components/ui/select/select-scroll-up-button.svelte create mode 100644 src/lib/components/ui/select/select-separator.svelte create mode 100644 src/lib/components/ui/select/select-trigger.svelte create mode 100644 src/lib/components/ui/select/select.svelte create mode 100644 src/lib/components/ui/separator/index.js create mode 100644 src/lib/components/ui/separator/separator.svelte create mode 100644 src/lib/components/ui/sheet/index.js create mode 100644 src/lib/components/ui/sheet/sheet-close.svelte create mode 100644 src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 src/lib/components/ui/sheet/sheet-trigger.svelte create mode 100644 src/lib/components/ui/sheet/sheet.svelte create mode 100644 src/lib/components/ui/sidebar/constants.js create mode 100644 src/lib/components/ui/sidebar/context.svelte.js create mode 100644 src/lib/components/ui/sidebar/index.js create mode 100644 src/lib/components/ui/sidebar/sidebar-content.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-footer.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-group-action.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-group-content.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-group-label.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-group.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-header.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-input.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-inset.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-action.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-badge.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-button.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-item.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu-sub.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-menu.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-provider.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-rail.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-separator.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar-trigger.svelte create mode 100644 src/lib/components/ui/sidebar/sidebar.svelte create mode 100644 src/lib/components/ui/skeleton/index.js create mode 100644 src/lib/components/ui/skeleton/skeleton.svelte create mode 100644 src/lib/components/ui/spinner/index.js create mode 100644 src/lib/components/ui/spinner/spinner.svelte create mode 100644 src/lib/components/ui/table/index.js create mode 100644 src/lib/components/ui/table/table-body.svelte create mode 100644 src/lib/components/ui/table/table-caption.svelte create mode 100644 src/lib/components/ui/table/table-cell.svelte create mode 100644 src/lib/components/ui/table/table-footer.svelte create mode 100644 src/lib/components/ui/table/table-head.svelte create mode 100644 src/lib/components/ui/table/table-header.svelte create mode 100644 src/lib/components/ui/table/table-row.svelte create mode 100644 src/lib/components/ui/table/table.svelte create mode 100644 src/lib/components/ui/tooltip/index.js create mode 100644 src/lib/components/ui/tooltip/tooltip-content.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-portal.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-provider.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-trigger.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip.svelte create mode 100644 src/lib/config/api.js create mode 100644 src/lib/hooks/is-mobile.svelte.js create mode 100644 src/lib/index.js create mode 100644 src/lib/utils.js create mode 100644 src/lib/utils/cleanEmptyStrings.js create mode 100644 src/lib/utils/formatUTCDate.js create mode 100644 src/lib/utils/getUrl.js create mode 100644 src/routes/+layout.server.js create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/+page.svelte create mode 100644 src/routes/api/preview/[...path]/+server.js create mode 100644 src/routes/api/upload/+server.js create mode 100644 src/routes/patient/+page.svelte create mode 100644 src/routes/sidebar-07/+page.svelte create mode 100644 static/robots.txt create mode 100644 svelte.config.js create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b462cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..7d74fe2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +# Package Managers +package-lock.json +pnpm-lock.yaml +yarn.lock +bun.lock +bun.lockb + +# Miscellaneous +/static/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..3f7802c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,15 @@ +{ + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "printWidth": 100, + "plugins": ["prettier-plugin-svelte"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..75842c4 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/components.json b/components.json new file mode 100644 index 0000000..3ace98c --- /dev/null +++ b/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src\\app.css", + "baseColor": "slate" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": false, + "registry": "https://shadcn-svelte.com/registry" +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..58fdcea --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,26 @@ +import prettier from 'eslint-config-prettier'; +import { fileURLToPath } from 'node:url'; +import { includeIgnoreFile } from '@eslint/compat'; +import js from '@eslint/js'; +import svelte from 'eslint-plugin-svelte'; +import globals from 'globals'; +import svelteConfig from './svelte.config.js'; + +const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url)); + +/** @type {import('eslint').Linter.Config[]} */ export default [ + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...svelte.configs.recommended, + prettier, + ...svelte.configs.prettier, + + { + languageOptions: { globals: { ...globals.browser, ...globals.node } } + }, + + { + files: ['**/*.svelte', '**/*.svelte.js'], + languageOptions: { parserOptions: { svelteConfig } } + } +]; diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..d73b913 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": false, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..63036bb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3742 @@ +{ + "name": "shadcn5", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "shadcn5", + "version": "0.0.1", + "dependencies": { + "@tailwindcss/vite": "^4.1.18", + "mime-types": "^3.0.2", + "mode-watcher": "^1.1.0", + "tailwindcss": "^4.1.18", + "zod": "^4.3.5" + }, + "devDependencies": { + "@eslint/compat": "^1.4.0", + "@eslint/js": "^9.39.1", + "@internationalized/date": "^3.10.1", + "@lucide/svelte": "^0.561.0", + "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/kit": "^2.49.1", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tanstack/table-core": "^8.21.3", + "@types/node": "^22", + "bits-ui": "^2.15.4", + "clsx": "^2.1.1", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.13.1", + "globals": "^16.5.0", + "prettier": "^3.7.4", + "prettier-plugin-svelte": "^3.4.0", + "svelte": "^5.45.6", + "tailwind-merge": "^3.4.0", + "tailwind-variants": "^3.2.2", + "tw-animate-css": "^1.4.0", + "vite": "^7.2.6" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/compat": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.1.tgz", + "integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^8.40 || 9" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@internationalized/date": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.1.tgz", + "integrity": "sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lucide/svelte": { + "version": "0.561.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.561.0.tgz", + "integrity": "sha512-vofKV2UFVrKE6I4ewKJ3dfCXSV6iP6nWVmiM83MLjsU91EeJcEg7LoWUABLp/aOTxj1HQNbJD1f3g3L0JQgH9A==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "svelte": "^5" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.8.tgz", + "integrity": "sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.0.tgz", + "integrity": "sha512-ImDWaErTOCkRS4Gt+5gZuymKFBobnhChXUZ9lhUZLahUgvA4OOvRzi3sahzYgbxGj5nkA6OV0GAW378+dl/gyw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.50.0.tgz", + "integrity": "sha512-Hj8sR8O27p2zshFEIJzsvfhLzxga/hWw6tRLnBjMYw70m1aS9BSYCqAUtzDBjRREtX1EvLMYgaC0mYE3Hz4KWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.6.2", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz", + "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "deepmerge": "^4.3.1", + "magic-string": "^0.30.21", + "obug": "^2.1.0", + "vitefu": "^1.1.1" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.2.tgz", + "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "obug": "^2.1.0" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.18", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", + "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", + "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", + "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-arm64": "4.1.18", + "@tailwindcss/oxide-darwin-x64": "4.1.18", + "@tailwindcss/oxide-freebsd-x64": "4.1.18", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", + "@tailwindcss/oxide-linux-x64-musl": "4.1.18", + "@tailwindcss/oxide-wasm32-wasi": "4.1.18", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", + "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", + "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", + "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", + "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", + "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", + "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", + "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", + "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", + "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", + "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.0", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", + "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", + "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz", + "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.18", + "@tailwindcss/oxide": "4.1.18", + "tailwindcss": "4.1.18" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.3.tgz", + "integrity": "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.7.tgz", + "integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bits-ui": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.15.4.tgz", + "integrity": "sha512-7H9YUfp03KOk1LVDh8wPYSRPxlZgG/GRWLNSA8QC73/8Z8ytun+DWJhIuibyFyz7A0cP/RANVcB4iDrbY8q+Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.1", + "@floating-ui/dom": "^1.7.1", + "esm-env": "^1.1.2", + "runed": "^0.35.1", + "svelte-toolbelt": "^0.10.6", + "tabbable": "^6.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/huntabyte" + }, + "peerDependencies": { + "@internationalized/date": "^3.8.1", + "svelte": "^5.33.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", + "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-svelte": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-3.14.0.tgz", + "integrity": "sha512-Isw0GvaMm0yHxAj71edAdGFh28ufYs+6rk2KlbbZphnqZAzrH3Se3t12IFh2H9+1F/jlDhBBL4oiOJmLqmYX0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.6.1", + "@jridgewell/sourcemap-codec": "^1.5.0", + "esutils": "^2.0.3", + "globals": "^16.0.0", + "known-css-properties": "^0.37.0", + "postcss": "^8.4.49", + "postcss-load-config": "^3.1.4", + "postcss-safe-parser": "^7.0.0", + "semver": "^7.6.3", + "svelte-eslint-parser": "^1.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": "^8.57.1 || ^9.0.0", + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrap": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.1.tgz", + "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mode-watcher": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.1.0.tgz", + "integrity": "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==", + "license": "MIT", + "dependencies": { + "runed": "^0.25.0", + "svelte-toolbelt": "^0.7.1" + }, + "peerDependencies": { + "svelte": "^5.27.0" + } + }, + "node_modules/mode-watcher/node_modules/runed": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.25.0.tgz", + "integrity": "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg==", + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "dependencies": { + "esm-env": "^1.0.0" + }, + "peerDependencies": { + "svelte": "^5.7.0" + } + }, + "node_modules/mode-watcher/node_modules/svelte-toolbelt": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz", + "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==", + "funding": [ + "https://github.com/sponsors/huntabyte" + ], + "dependencies": { + "clsx": "^2.1.1", + "runed": "^0.23.2", + "style-to-object": "^1.0.8" + }, + "engines": { + "node": ">=18", + "pnpm": ">=8.7.0" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } + }, + "node_modules/mode-watcher/node_modules/svelte-toolbelt/node_modules/runed": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", + "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "dependencies": { + "esm-env": "^1.0.0" + }, + "peerDependencies": { + "svelte": "^5.7.0" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.29" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.0.tgz", + "integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-svelte": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.4.1.tgz", + "integrity": "sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "prettier": "^3.0.0", + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rollup": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/runed": { + "version": "0.35.1", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.35.1.tgz", + "integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "esm-env": "^1.0.0", + "lz-string": "^1.5.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.21.0", + "svelte": "^5.7.0" + }, + "peerDependenciesMeta": { + "@sveltejs/kit": { + "optional": true + } + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "dev": true, + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svelte": { + "version": "5.46.4", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.46.4.tgz", + "integrity": "sha512-VJwdXrmv9L8L7ZasJeWcCjoIuMRVbhuxbss0fpVnR8yorMmjNDwcjIH08vS6wmSzzzgAG5CADQ1JuXPS2nwt9w==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.6.2", + "esm-env": "^1.2.1", + "esrap": "^2.2.1", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-eslint-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-1.4.1.tgz", + "integrity": "sha512-1eqkfQ93goAhjAXxZiu1SaKI9+0/sxp4JIWQwUpsz7ybehRE5L8dNuz7Iry7K22R47p5/+s9EM+38nHV2OlgXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.0", + "postcss": "^8.4.49", + "postcss-scss": "^4.0.9", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0", + "pnpm": "10.24.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, + "node_modules/svelte-toolbelt": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", + "integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte" + ], + "dependencies": { + "clsx": "^2.1.1", + "runed": "^0.35.1", + "style-to-object": "^1.0.8" + }, + "engines": { + "node": ">=18", + "pnpm": ">=8.7.0" + }, + "peerDependencies": { + "svelte": "^5.30.2" + } + }, + "node_modules/tabbable": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", + "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-variants": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.2.2.tgz", + "integrity": "sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.x", + "pnpm": ">=7.x" + }, + "peerDependencies": { + "tailwind-merge": ">=3.0.0", + "tailwindcss": "*" + }, + "peerDependenciesMeta": { + "tailwind-merge": { + "optional": true + } + } + }, + "node_modules/tailwindcss": { + "version": "4.1.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", + "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "devOptional": true, + "license": "0BSD" + }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT" + }, + "node_modules/zod": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6b86b98 --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "shadcn5", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "format": "prettier --write .", + "lint": "prettier --check . && eslint ." + }, + "devDependencies": { + "@eslint/compat": "^1.4.0", + "@eslint/js": "^9.39.1", + "@internationalized/date": "^3.10.1", + "@lucide/svelte": "^0.561.0", + "@sveltejs/adapter-auto": "^7.0.0", + "@sveltejs/kit": "^2.49.1", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tanstack/table-core": "^8.21.3", + "@types/node": "^22", + "bits-ui": "^2.15.4", + "clsx": "^2.1.1", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-svelte": "^3.13.1", + "globals": "^16.5.0", + "prettier": "^3.7.4", + "prettier-plugin-svelte": "^3.4.0", + "svelte": "^5.45.6", + "tailwind-merge": "^3.4.0", + "tailwind-variants": "^3.2.2", + "tw-animate-css": "^1.4.0", + "vite": "^7.2.6" + }, + "dependencies": { + "@tailwindcss/vite": "^4.1.18", + "mime-types": "^3.0.2", + "mode-watcher": "^1.1.0", + "tailwindcss": "^4.1.18", + "zod": "^4.3.5" + } +} diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..e48f5f0 --- /dev/null +++ b/src/app.css @@ -0,0 +1,121 @@ +@import "tailwindcss"; + +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.129 0.042 264.695); + --card: oklch(1 0 0); + --card-foreground: oklch(0.129 0.042 264.695); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.129 0.042 264.695); + --primary: oklch(0.208 0.042 265.755); + --primary-foreground: oklch(0.984 0.003 247.858); + --secondary: oklch(0.968 0.007 247.896); + --secondary-foreground: oklch(0.208 0.042 265.755); + --muted: oklch(0.968 0.007 247.896); + --muted-foreground: oklch(0.554 0.046 257.417); + --accent: oklch(0.968 0.007 247.896); + --accent-foreground: oklch(0.208 0.042 265.755); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.929 0.013 255.508); + --input: oklch(0.929 0.013 255.508); + --ring: oklch(0.704 0.04 256.788); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.984 0.003 247.858); + --sidebar-foreground: oklch(0.129 0.042 264.695); + --sidebar-primary: oklch(0.208 0.042 265.755); + --sidebar-primary-foreground: oklch(0.984 0.003 247.858); + --sidebar-accent: oklch(0.968 0.007 247.896); + --sidebar-accent-foreground: oklch(0.208 0.042 265.755); + --sidebar-border: oklch(0.929 0.013 255.508); + --sidebar-ring: oklch(0.704 0.04 256.788); +} + +.dark { + --background: oklch(0.129 0.042 264.695); + --foreground: oklch(0.984 0.003 247.858); + --card: oklch(0.208 0.042 265.755); + --card-foreground: oklch(0.984 0.003 247.858); + --popover: oklch(0.208 0.042 265.755); + --popover-foreground: oklch(0.984 0.003 247.858); + --primary: oklch(0.929 0.013 255.508); + --primary-foreground: oklch(0.208 0.042 265.755); + --secondary: oklch(0.279 0.041 260.031); + --secondary-foreground: oklch(0.984 0.003 247.858); + --muted: oklch(0.279 0.041 260.031); + --muted-foreground: oklch(0.704 0.04 256.788); + --accent: oklch(0.279 0.041 260.031); + --accent-foreground: oklch(0.984 0.003 247.858); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.551 0.027 264.364); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.208 0.042 265.755); + --sidebar-foreground: oklch(0.984 0.003 247.858); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.984 0.003 247.858); + --sidebar-accent: oklch(0.279 0.041 260.031); + --sidebar-accent-foreground: oklch(0.984 0.003 247.858); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.551 0.027 264.364); +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..f273cc5 --- /dev/null +++ b/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/lib/api/api-client.js b/src/lib/api/api-client.js new file mode 100644 index 0000000..c929ee8 --- /dev/null +++ b/src/lib/api/api-client.js @@ -0,0 +1,110 @@ +import { API } from '$lib/config/api.js'; +import { cleanEmptyStrings } from '$lib/utils/cleanEmptyStrings'; + +function cleanQuery(searchQuery) { + const result = {}; + for (const key in searchQuery) { + if ( + searchQuery[key] !== null && + searchQuery[key] !== undefined && + searchQuery[key] !== '' + ) { + result[key] = searchQuery[key]; + } + } + return result; +} + +export async function getById(endpoint, id) { + try { + const res = await fetch(`${API.BASE_URL}${endpoint}/${id}`); + + if (!res.ok) { + const error = await res.json(); + console.error('API Error:', error); + return { data: null, error }; + } + + const response = await res.json(); + return { data: response.data?.[0] || response.data, error: null }; + } catch (err) { + console.error('Network Error:', err); + return { data: null, error: err }; + } +} + +export async function searchWithParams(endpoint, searchQuery) { + try { + const cleanSearchQuery = cleanQuery(searchQuery); + const params = new URLSearchParams(cleanSearchQuery).toString(); + const url = params + ? `${API.BASE_URL}${endpoint}?${params}` + : `${API.BASE_URL}${endpoint}`; + + const res = await fetch(url); + const data = await res.json(); + return data.data || []; + } catch (err) { + console.error('Search Error:', err); + return []; + } +} + +export async function searchWithPath(endpoint, searchQuery) { + try { + const entries = Object.entries(searchQuery) + .filter(([_, v]) => v !== null && v !== undefined && v !== ''); + + let url = `${API.BASE_URL}${endpoint}`; + + if (entries.length > 0) { + const path = entries.map(([k, v]) => `${k}/${v}`).join('/'); + url = `${url}/${path}`; + } + + const res = await fetch(url); + const data = await res.json(); + return data.data || []; + } catch (err) { + console.error('Search Error:', err); + return []; + } +} + +export async function create(endpoint, formData) { + console.log(cleanEmptyStrings(formData)); + try { + const res = await fetch(`${API.BASE_URL}${endpoint}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(cleanEmptyStrings(formData)) + }); + + const data = await res.json(); + return data; + } catch (err) { + console.error('Create Error:', err.message); + return { success: false, message: err.message || 'Network error' }; + } +} + +export async function update(endpoint, formData) { + console.log(cleanEmptyStrings(formData)); + try { + const res = await fetch(`${API.BASE_URL}${endpoint}`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(cleanEmptyStrings(formData)) + }); + + const data = await res.json(); + return data; + } catch (err) { + console.error('Update Error:', err.message); + return { success: false, message: err.message || 'Network error' }; + } +} \ No newline at end of file diff --git a/src/lib/assets/favicon.svg b/src/lib/assets/favicon.svg new file mode 100644 index 0000000..cc5dc66 --- /dev/null +++ b/src/lib/assets/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte new file mode 100644 index 0000000..945ccf8 --- /dev/null +++ b/src/lib/components/app-sidebar.svelte @@ -0,0 +1,166 @@ + + + + + + + + + + {#snippet child({ props })} + +
+ +
+
+ 5PANDAWA + Tilis +
+
+ {/snippet} +
+
+
+
+ + + + + + + +
\ No newline at end of file diff --git a/src/lib/components/composable/use-form-option.svelte.js b/src/lib/components/composable/use-form-option.svelte.js new file mode 100644 index 0000000..67deb3c --- /dev/null +++ b/src/lib/components/composable/use-form-option.svelte.js @@ -0,0 +1,99 @@ +const optionsMode = { + default: async (field, selectOptions, loadingOptions) => { + if (selectOptions[field.key]?.length > 0) return; + + loadingOptions[field.key] = true; + + try { + const res = await fetch(field.optionsEndpoint); + const json = await res.json(); + + selectOptions[field.key] = json?.data ?? []; + + } catch (err) { + console.error("Failed to fetch options for", field.key, err); + selectOptions[field.key] = []; + } finally { + loadingOptions[field.key] = false; + } + }, + + cascade: async (field, selectOptions, loadingOptions, form, lastFetched) => { + const parentValue = field.dependsOn ? form?.[field.dependsOn] : null; + + // If has dependency and parent changed, or not fetched yet + if (field.dependsOn) { + // If parent value exists and already fetched for this parent value, skip + if (selectOptions[field.key]?.length > 0 && + lastFetched[field.key] === parentValue) { + return; + } + + // If no parent value, clear options + if (!parentValue) { + selectOptions[field.key] = []; + return; + } + } else { + // Non-dependent field, only fetch once + if (selectOptions[field.key]?.length > 0) return; + } + + let endpoint = field.optionsEndpoint; + + // Add parent parameter if exists + if (parentValue && field.endpointParamKey) { + endpoint += `?${field.endpointParamKey}=${parentValue}`; + } + + loadingOptions[field.key] = true; + + try { + const res = await fetch(endpoint); + const json = await res.json(); + + selectOptions[field.key] = json?.data ?? []; + + // Track last fetched parent value for dependent fields + if (field.dependsOn) { + lastFetched[field.key] = parentValue; + } + } catch (err) { + console.error("Failed to fetch options for", field.key, err); + selectOptions[field.key] = []; + } finally { + loadingOptions[field.key] = false; + } + } +}; + +export function useFormOptions(optMode = 'default') { + const selectOptions = $state({}); + const loadingOptions = $state({}); + const lastFetched = $state({}); + + async function fetchOptions(field, form = null) { + if (!field?.optionsEndpoint) return; + + const modeFn = optionsMode[optMode]; + if (!modeFn) return; + + await modeFn(field, selectOptions, loadingOptions, form, lastFetched); + } + + function clearDependentOptions(parentKey, dependentKeys, form) { + dependentKeys.forEach(key => { + selectOptions[key] = []; + if (form) form[key] = ''; + lastFetched[key] = null; + }); + } + + return { + selectOptions, + loadingOptions, + lastFetched, + fetchOptions, + clearDependentOptions, + }; +} \ No newline at end of file diff --git a/src/lib/components/composable/use-form-state.svelte.js b/src/lib/components/composable/use-form-state.svelte.js new file mode 100644 index 0000000..a2b145e --- /dev/null +++ b/src/lib/components/composable/use-form-state.svelte.js @@ -0,0 +1,15 @@ +export function useFormState(initial) { + const form = $state(structuredClone(initial)) + const isSaving = $state({ current: false }); + + function resetForm() { + Object.assign(form, structuredClone(initial)); + } + + function setForm(data) { + const snapshotData = $state.snapshot(data); + Object.assign(form, JSON.parse(JSON.stringify(snapshotData))); + } + + return { isSaving, form, resetForm, setForm } +} \ No newline at end of file diff --git a/src/lib/components/composable/use-form-validation.svelte.js b/src/lib/components/composable/use-form-validation.svelte.js new file mode 100644 index 0000000..3330c31 --- /dev/null +++ b/src/lib/components/composable/use-form-validation.svelte.js @@ -0,0 +1,31 @@ +const validationMode = { + create: (schema, field, value) => { + const result = schema.shape[field].safeParse(value); + return result.success ? null : result.error.issues[0].message; + }, + + edit: (schema, field, value, originalValue) => { + if (originalValue !== undefined && value === originalValue) { + return null; + } + + const result = schema.shape[field].safeParse(value); + return result.success ? null : result.error.issues[0].message; + } +}; + +export function useFormValidation(schema, form, defaultErrors, valMode) { + const errors = $state({...defaultErrors}) + + function validateField(field, originalValue) { + const value = form[field]; + const valFn = validationMode[valMode]; + errors[field] = valFn(schema, field, value, originalValue); + } + + function resetErrors() { + Object.assign(errors, defaultErrors); + } + + return { errors, validateField, resetErrors } +} \ No newline at end of file diff --git a/src/lib/components/composable/use-form.svelte.js b/src/lib/components/composable/use-form.svelte.js new file mode 100644 index 0000000..1e95610 --- /dev/null +++ b/src/lib/components/composable/use-form.svelte.js @@ -0,0 +1,37 @@ +import { useFormState } from "./use-form-state.svelte"; +import { useFormOptions } from "./use-form-option.svelte"; +import { useFormValidation } from "./use-form-validation.svelte"; + +export function useForm({schema, initialForm, defaultErrors, mode, modeOpt, saveEndpoint, editEndpoint}) { + const state = useFormState(initialForm); + const val = useFormValidation(schema, state.form, defaultErrors, mode); + const options = useFormOptions(modeOpt); + + async function save() { + state.isSaving.current = true + + try { + const payload = { ...state.form }; + const result = mode === 'edit' ? await editEndpoint(payload) : await saveEndpoint(payload) + return result; + } catch (error) { + console.error('Save failed', error); + return { status: 'error', message: 'Save failed' }; + } finally { + state.isSaving.current = false; + } + } + + function reset() { + state.resetForm(); + val.resetErrors(); + } + + return { + ...state, //form, resetForm, setForm, isSaving + ...val, //errors, validateField, resetErrors + ...options, //selectOptions, loadingOptions, fetchOptions, lastFetched, clearDependentOptions + save, + reset, + } +} \ No newline at end of file diff --git a/src/lib/components/composable/use-patient-form.svelte.js b/src/lib/components/composable/use-patient-form.svelte.js new file mode 100644 index 0000000..9c7c35b --- /dev/null +++ b/src/lib/components/composable/use-patient-form.svelte.js @@ -0,0 +1,102 @@ +import { API } from "$lib/config/api"; +import { z } from "zod"; + +export function usePatientForm(formState, patientSchema) { + let uploadErrors = $state({}); + let isChecking = $state({}); + + async function validateFieldAsync(field) { + isChecking[field] = true; + + try { + const asyncSchema = patientSchema.extend({ + PatientID: patientSchema.shape.PatientID.refine( + async (value) => { + if (!value) return false; + const res = await fetch(`${API.BASE_URL}${API.CHECK}?PatientID=${value}`); + const { status, data } = await res.json(); + return status === "success" && data === false ? false : true; + }, + { message: "Patient ID already used" } + ) + }); + + const partial = asyncSchema.pick({ [field]: true }); + const result = await partial.safeParseAsync({ [field]: formState.form[field] }); + + formState.errors[field] = result.success ? null : result.error.issues[0].message; + } catch (err) { + console.error('Async validation error:', err); + } finally { + isChecking[field] = false; + } + } + + function validateIdentifier() { + const identifierType = formState.form.PatIdt.IdentifierType; + const identifierValue = formState.form.PatIdt.Identifier; + if (!identifierType || !identifierValue) { + formState.errors['PatIdt.Identifier'] = null; + return; + } + + const schema = getIdentifierValidation(identifierType); + const result = schema.safeParse(identifierValue); + + formState.errors['PatIdt.Identifier'] = result.success ? null : result.error.issues[0].message; + } + + function getIdentifierValidation(identifierType) { + switch (identifierType) { + case 'KTP': + return z.string() + .length(16, "Must be 16 characters") + .regex(/^$|^[0-9]+$/, "Can only contain numbers"); + + case 'PASS': + return z.string() + .max(9, "Max 9 chars") + .regex(/^[A-Z0-9]+$/, "Must be uppercase letters and numbers"); + + case 'SSN': + return z.string() + .max(9, "Max 9 chars") + .regex(/^$|^[0-9]+$/, "Can only contain numbers"); + + case 'SIM': + return z.string() + .max(20, "Max 20 chars") + .regex(/^$|^[0-9]+$/, "Can only contain numbers"); + + case 'KTAS': + return z.string() + .max(11, "Max 11 chars") + .regex(/^[A-Z0-9]+$/, "Must be uppercase letters and numbers"); + + default: + return z.string().min(1, "Identifier required"); + } + } + + let linkToDisplay = $derived( + Array.isArray(formState.form.LinkTo) + ? formState.form.LinkTo + .map(p => p.PatientID) + .filter(Boolean) + .join(', ') + : '' + ); + + let hasErrors = $derived( + Object.values(formState.errors).some(value => value !== null) + ); + + return { + uploadErrors, + isChecking, + validateFieldAsync, + validateIdentifier, + get linkToDisplay() { return linkToDisplay }, + get hasErrors() { return hasErrors }, + } +} \ No newline at end of file diff --git a/src/lib/components/composable/useMasterDetail.svelte.js b/src/lib/components/composable/useMasterDetail.svelte.js new file mode 100644 index 0000000..a82613f --- /dev/null +++ b/src/lib/components/composable/useMasterDetail.svelte.js @@ -0,0 +1,136 @@ +import { useResponsive } from "./useResponsive.svelte.js"; + +export function useMasterDetail(options = {}) { + const { confirmMessage = "You have unsaved changes. Discard them?", onSelect = null, } = options; + + let selectedItem = $state(null); + let mode = $state("view"); + let isLoadingDetail = $state(false); + + // Form state + let form = $state({}); + let formSnapshot = $state({}); + + const { isMobile } = useResponsive(); + + // Derived states + const isFormMode = $derived(mode === "create" || mode === "edit"); + + const showMaster = $derived(!isMobile || (mode === "view" && !selectedItem)); + + const showDetail = $derived(!isMobile || selectedItem || isFormMode); + + const layout = $derived({ + masterWidth: isMobile ? "w-full" : isFormMode ? "w-[3%]" : "w-[35%]", + detailWidth: isMobile ? "w-full" : isFormMode ? "w-[97%]" : "w-[65%]", + }); + + const isDirty = $derived( + JSON.stringify(form) !== JSON.stringify(formSnapshot) + ); + + // Actions + async function select(item) { + mode = "view"; + + if (onSelect) { + isLoadingDetail = true; + try { + const detailData = await onSelect(item); + selectedItem = detailData; + } catch (error) { + console.error("Failed to fetch detail:", error); + selectedItem = null; + } finally { + isLoadingDetail = false; + } + } else { + selectedItem = item; + } + } + + function enterCreate(initialValues = {}) { + mode = "create"; + selectedItem = null; + form = { ...initialValues }; + formSnapshot = { ...initialValues }; + } + + function enterEdit(mapToForm = null) { + if (!selectedItem) return; + mode = "edit"; + + // Auto exclude 'id' or use custom mapping + const formData = mapToForm + ? mapToForm(selectedItem) + : (() => { + const { id, ...rest } = selectedItem; + return rest; + })(); + + form = { ...formData }; + formSnapshot = { ...formData }; + } + + function exitForm(force = false) { + if (!force && isDirty) { + const ok = confirm(confirmMessage); + if (!ok) return; + } + + mode = "view"; + selectedItem = null; + } + + function backToList() { + selectedItem = null; + mode = "view"; + } + + function saveForm() { + // Commit changes (mark as saved) + formSnapshot = { ...form }; + } + + return { + // State + get selectedItem() { + return selectedItem; + }, + get mode() { + return mode; + }, + get isFormMode() { + return isFormMode; + }, + get isMobile() { + return isMobile; + }, + get showMaster() { + return showMaster; + }, + get showDetail() { + return showDetail; + }, + get layout() { + return layout; + }, + get form() { + return form; + }, + get isDirty() { + return isDirty; + }, + get isLoadingDetail() { + return isLoadingDetail; + }, + + // Actions + select, + enterCreate, + enterEdit, + exitForm, + backToList, + saveForm, + }; +} \ No newline at end of file diff --git a/src/lib/components/composable/useResponsive.svelte.js b/src/lib/components/composable/useResponsive.svelte.js new file mode 100644 index 0000000..cb1e777 --- /dev/null +++ b/src/lib/components/composable/useResponsive.svelte.js @@ -0,0 +1,20 @@ +export function useResponsive(breakpoint = 768) { + let isMobile = $state(false); + + $effect(() => { + const checkMobile = () => { + isMobile = window.innerWidth < breakpoint; + }; + + checkMobile(); + window.addEventListener("resize", checkMobile); + + return () => window.removeEventListener("resize", checkMobile); + }); + + return { + get isMobile() { + return isMobile; + }, + }; +} \ No newline at end of file diff --git a/src/lib/components/composable/useSearch.svelte.js b/src/lib/components/composable/useSearch.svelte.js new file mode 100644 index 0000000..2c37b00 --- /dev/null +++ b/src/lib/components/composable/useSearch.svelte.js @@ -0,0 +1,41 @@ +export function useSearch(searchFields, searchApiFunction) { + let searchQuery = $state(initializeSearchQuery(searchFields)); + let isLoading = $state(false); + let searchData = $state([]); + + function initializeSearchQuery(fields) { + const query = {}; + for (const field of fields) { + if (field.type === "select") { + query[field.key] = field.default ?? ""; + } else { + query[field.key] = ""; + } + } + return query; + } + + async function handleSearch() { + isLoading = true; + try { + searchData = await searchApiFunction(searchQuery); + } catch (error) { + console.error('Search failed:', error); + } finally { + isLoading = false; + } + } + + function handleReset() { + searchQuery = initializeSearchQuery(searchFields); + } + + return { + get searchQuery() { return searchQuery; }, + set searchQuery(value) { searchQuery = value; }, + get searchData() { return searchData; }, + get isLoading() { return isLoading; }, + handleSearch, + handleReset + }; +} \ No newline at end of file diff --git a/src/lib/components/nav-dictionary.svelte b/src/lib/components/nav-dictionary.svelte new file mode 100644 index 0000000..d000d9a --- /dev/null +++ b/src/lib/components/nav-dictionary.svelte @@ -0,0 +1,61 @@ + + + + Dictionary + + {#each dictionary as item (item.title)} + + + + {#snippet child({ props })} + + + {item.title} + + {/snippet} + + {#if item.items?.length} + + {#snippet child({ props })} + + + Toggle + + {/snippet} + + + + {#each item.items as subItem (subItem.title)} + + + {subItem.title} + + + {/each} + + + {/if} + + + {/each} + + \ No newline at end of file diff --git a/src/lib/components/nav-main.svelte b/src/lib/components/nav-main.svelte new file mode 100644 index 0000000..649a6f0 --- /dev/null +++ b/src/lib/components/nav-main.svelte @@ -0,0 +1,115 @@ + + + + Menu + + {#each items as item, index} + {#if sidebar.state === "expanded"} + + {#snippet child({ props })} + + + {#snippet child({ props })} + {#if item.submenus?.length} + + + {item.title} + + {:else} + + + {item.title} + + {/if} + {/snippet} + + {#if item.submenus?.length} + + {#snippet child({ props })} + + + Toggle + + {/snippet} + + + + {#each item.submenus as subItem (subItem.title)} + + + {subItem.title} + + + {/each} + + + {/if} + + {/snippet} + + {:else} + openPopovers[item.url] = open}> + + {#snippet trigger(props)} + + + {#if item.icon && !item.submenu} + + {/if} + {item.title} + + + {/snippet} + {@render trigger()} + + + + + + + {/if} + {/each} + + \ No newline at end of file diff --git a/src/lib/components/nav-user.svelte b/src/lib/components/nav-user.svelte new file mode 100644 index 0000000..f644047 --- /dev/null +++ b/src/lib/components/nav-user.svelte @@ -0,0 +1,87 @@ + + + + + + + {#snippet child({ props })} + + + + CN + +
+ {user.name} + {user.email} +
+ +
+ {/snippet} +
+ + +
+ + + CN + +
+ {user.name} + {user.email} +
+
+
+ + + + + Upgrade to Pro + + + + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
\ No newline at end of file diff --git a/src/lib/components/patient/api/patient-api.js b/src/lib/components/patient/api/patient-api.js new file mode 100644 index 0000000..38d04e3 --- /dev/null +++ b/src/lib/components/patient/api/patient-api.js @@ -0,0 +1,21 @@ +import { API } from '$lib/config/api.js'; +import { getById, searchWithParams, create, update } from '$lib/api/api-client'; + +export async function searchParam(searchQuery) { + return await searchWithParams(API.PATIENTS, searchQuery) +} + +export async function getPatient(searchQuery) { + const { data: patient, error } = await getById(API.PATIENTS, searchQuery) + return { patient }; +} + +export async function createPatient(newContactForm) { + // console.log(JSON.stringify(newContactForm)); + return await create(API.PATIENTS, newContactForm) +} + +export async function editPatient(editContactForm) { + // console.log(JSON.stringify(editContactForm)); + return await update(API.PATIENTS, editContactForm) +} \ No newline at end of file diff --git a/src/lib/components/patient/config/patient-config.js b/src/lib/components/patient/config/patient-config.js new file mode 100644 index 0000000..945c52e --- /dev/null +++ b/src/lib/components/patient/config/patient-config.js @@ -0,0 +1,145 @@ +import PlusIcon from "@lucide/svelte/icons/plus"; +import Settings2Icon from "@lucide/svelte/icons/settings-2"; +import FlaskConicalIcon from "@lucide/svelte/icons/flask-conical"; +import ActivityIcon from "@lucide/svelte/icons/activity"; +import PencilIcon from "@lucide/svelte/icons/pencil"; +import NotepadTextIcon from "@lucide/svelte/icons/notepad-text"; + +export const searchFields = [ + { + key: "PatientID", + label: "Patient ID", + placeholder: "", + type: "text", + defaultValue: "", + }, + { + key: "Name", + label: "Patient Name", + placeholder: "", + type: "text", + defaultValue: "", + }, + { + key: "Birthdate", + label: "Birthdate", + type: "date" + }, +]; + +export const detailSections = [ + { + class: "grid grid-cols-2 lg:grid-cols-3 gap-3", + fields: [ + { key: "PatientID", label: "Patient ID", }, + { parentKey: "PatIdt", key: "IdentifierType", label: "Identifier Type", }, + { key: "Birthdate", label: "Date of Birth", }, + { key: "SexLabel", label: "Sex", }, + { parentKey: "PatIdt", key: "Identifier", label: "Identifier", }, + { key: "Age", label: "Age", }, + ] + }, + { + class: "grid grid-cols-1 sm:grid-cols-3 gap-3", + fields: [ + { key: "ReligionLabel", label: "Religion" }, + { keys: ["Street_1", "Street_2", "Street_3"], className: "row-span-2", label: "Address" }, + { key: "EmailAddress1", label: "Email Address 1" }, + { key: "MaritalStatusLabel", label: "Marital Status" }, + { key: "EmailAddress2", label: "Email Address 2" }, + { key: "EthnicLabel", label: "Ethnic" }, + { + isGroup: true, + class: "grid grid-cols-2", + fields: [ + { key: "City", label: "City" }, + { key: "ZIP", label: "ZIP" }, + ], + }, + { key: "Phone", label: "Phone" }, + { key: "RaceLabel", label: "Race" }, + { + isGroup: true, + class: "grid grid-cols-2", + fields: [ + { key: "Province", label: "Province" }, + { key: "CountryLabel", label: "Country" }, + ], + }, + { key: "MobilePhone", label: "Mobile Phone" }, + { key: "Citizenship", label: "Citizenship" }, + { + isGroup: true, + class: "grid grid-cols-2", + fields: [ + { key: "LinkTo", label: "Link Patient" }, + { parentKey: "Custodian", key: "PatientID", label: "Custodian ID" }, + ], + }, + { key: "DeathIndicatorLabel", label: "Death Indicator" }, + { key: "CreateDate", label: "Create Date", isUTCDate: true }, + { key: "DelDate", label: "Disabled Date" }, + { key: "TimeOfDeath", label: "Death Date", isUTCDate: true }, + ] + }, + { + class: "grid grid-cols-1 sm:grid-cols-2 gap-3", + fields: [ + { key: "", label: "Patient Visit ID" }, + { key: "", label: "Insurance" }, + { key: "", label: "Visit Class" }, + { key: "", label: "Service Class" }, + { key: "", label: "Location" }, + { key: "", label: "Doctor" }, + { key: "", label: "Admission Date", isUTCDate: true }, + { key: "", label: "Discharge Date", isUTCDate: true }, + ] + }, + { + class: "grid grid-cols-1 sm:grid-cols-2 gap-3", + fields: [ + { key: "PatCom", label: "Patient Comment" }, + { key: "PatAtt", label: "Patient File", isFileList: true }, + ] + } +] + +export function patientActions(masterDetail) { + return [ + { + Icon: PlusIcon, + label: 'Add Patient', + onClick: masterDetail.enterCreate, + }, + { + Icon: Settings2Icon, + label: 'Search Parameters', + }, + ]; +} + +export function viewActions(handlers){ + return [ + { + Icon: FlaskConicalIcon, + label: 'Order Lab', + onClick: handlers.orderLab, + }, + { + Icon: ActivityIcon, + label: 'Medical Record', + onClick: handlers.medicalRecord, + }, + { + Icon: NotepadTextIcon, + label: 'Audit Patient', + onClick: handlers.auditPatient, + }, + { + Icon: PencilIcon, + label: 'Edit Patient', + onClick: handlers.editPatient, + + }, + ] +} \ No newline at end of file diff --git a/src/lib/components/patient/config/patient-form-config.js b/src/lib/components/patient/config/patient-form-config.js new file mode 100644 index 0000000..58827e6 --- /dev/null +++ b/src/lib/components/patient/config/patient-form-config.js @@ -0,0 +1,311 @@ +import { API } from "$lib/config/api"; +import EraserIcon from "@lucide/svelte/icons/eraser"; +import { z } from "zod"; + +export const patientSchema = z.object({ + PatientID: z.string().min(1, "Required"), + Sex: z.string().min(1, "Required"), + NameFirst: z.string().min(1, "Required"), + Birthdate: z.string().min(1, "Required").refine( + (date) => new Date(date) <= new Date(), + "Cannot exceed today's date" + ), + EmailAddress1: z.string().min(1, "Required").email("Invalid email format"), + EmailAddress2: z.string().trim().optional().refine((val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),"Invalid email format"), + Phone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), + MobilePhone: z.string().max(14, "Max 14 chars").regex(/^$|^[0-9]+$/, "Can only contain numbers"), + TimeOfDeath: z.string().optional(), +}); + +export const patientInitialForm = { + PatientID: "", + AlternatePID: "", + PatIdt: { + IdentifierType: "", + Identifier: "" + }, + NameFirst: "", + Prefix: "", + Sex: "", + Religion: "", + NameMiddle: "", + NameMaiden: "", + MaritalStatus: "", + NameLast: "", + Custodian: { + InternalPID: "", + PatientID: "" + }, + Ethnic: "", + Suffix: "", + PlaceOfBirth: "", + Race: "", + Birthdate: "", + Citizenship: "", + Street_1: "", + City: "", + Street_2: "", + Province: "", + Street_3: "", + ZIP: "", + Country: "", + EmailAddress1: "", + Phone: "", + EmailAddress2: "", + MobilePhone: "", + DeathIndicator: "", + TimeOfDeath: "", + LinkTo: [], + PatCom: "", + PatAtt: [], +}; + +export const patientDefaultErrors = { + PatientID: "Required", + NameFirst: "Required", + Sex: "Required", + Birthdate: "Required", + EmailAddress1: "Required", + EmailAddress2: null, + 'PatIdt.Identifier': null, + Phone: null, + MobilePhone: null, +}; + +export const patientFormFields = [ + { + title: "", + rows: [ + { + type: "row", + columns: [ + { + key: "PatientID", + label: "Patient ID", + required: true, + type: "text", + validateOn: ["input", "blur"] + }, + { + key: "AlternatePID", + label: "Alternate PID", + required: false, + type: "text" + }, + { + key: "PatIdt.Identifier", + label: "Identifier", + required: false, + type: "identity", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/identifier_type`, + } + ] + } + ] + }, + { + title: "Personal Information", + rows: [ + { + type: "row", + columns: [ + { + key: "NameFirst", + label: "First Name", + required: true, + type: "text", + validateOn: ["input"] + }, + { + type: "group", + columns: [ + { + key: "Prefix", + label: "Prefix", + required: false, + type: "text" + }, + ] + }, + { + key: "Religion", + label: "Religion", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/religion`, + } + ] + }, + { + type: "row", + columns: [ + { key: "NameMiddle", label: "Middle Name", required: false, type: "text" }, + { key: "NameMaiden", label: "Maiden Name", required: false, type: "text" }, + { + key: "MaritalStatus", + label: "Marital Status", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/marital_status`, + } + ] + }, + { + type: "row", + columns: [ + { key: "NameLast", label: "Last Name", required: false, type: "text" }, + { key: "Custodian", label: "Custodian", required: false, type: "custodian" }, + { + key: "Ethnic", + label: "Ethnic", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/ethnic`, + } + ] + }, + { + type: "row", + columns: [ + { key: "Suffix", label: "Suffix", required: false, type: "text" }, + { key: "PlaceOfBirth", label: "Place of Birth", required: false, type: "text" }, + { + key: "Race", + label: "Race", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/race`, + } + ] + }, + { + type: "row", + columns: [ + { + key: "Sex", + label: "Sex", + required: true, + type: "select", + validateOn: ["input"], + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/sex`, + }, + { key: "Birthdate", label: "Birthdate", required: true, type: "date", validateOn: ["input"] }, + { key: "Citizenship", label: "Citizenship", required: false, type: "text" } + ] + } + ] + }, + { + title: "Address Information", + rows: [ + { + type: "row", + columns: [ + { key: "Street_1", label: "Street 1", required: false, type: "text" }, + { + key: "Province", + label: "Province", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.PROVINCE}`, + } + ] + }, + { + type: "row", + columns: [ + { key: "Street_2", label: "Street 2", required: false, type: "text" }, + { + key: "City", + label: "City", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.CITY}`, + dependsOn: "Province", // ← field yang jadi parent + endpointParamKey: "Parent" // ← query param name + } + ] + }, + { + type: "row", + columns: [ + { key: "Street_3", label: "Street 3", required: false, type: "text" }, + { + type: "group", + columns: [ + { key: "ZIP", label: "ZIP", required: false, type: "number" }, + { + key: "Country", + label: "Country", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/country`, + } + ] + } + ] + } + ] + }, + { + title: "Contact & Other Info", + rows: [ + { + type: "row", + columns: [ + { key: "EmailAddress1", label: "Email Address 1", required: true, type: "email", validateOn: ["input", "blur"] }, + { key: "Phone", label: "Phone", required: false, type: "text", validateOn: ["input"] }, + ] + }, + { + type: "row", + columns: [ + { key: "EmailAddress2", label: "Email Address 2", required: false, type: "email", validateOn: ["input"] }, + { key: "MobilePhone", label: "Mobile Phone", required: false, type: "text", validateOn: ["input"] }, + ] + }, + { + type: "row", + columns: [ + { + type: "group", + columns: [ + { + key: "DeathIndicator", + label: "Deceased", + required: false, + type: "select", + optionsEndpoint: `${API.BASE_URL}${API.VALUESET}/death_indicator`, + defaultValue: 'N' + }, + { key: "TimeOfDeath", label: "Time of Death", required: false, type: "datetime" } + ] + }, + { key: "LinkTo", label: "Link To", required: false, type: "linkto" } + ] + } + ] + }, + { + title: "Additional Documents", + rows: [ + { + type: "row", + columns: [ + { key: "PatCom", label: "Patient Comment", required: false, type: "textarea" }, + { key: "PatAtt", label: "Patient File", required: false, type: "fileupload" } + ] + } + ] + } +]; + +export function getPatientFormActions(handlers) { + return [ + { + Icon: EraserIcon, + label: 'Clear Form', + onClick: handlers.clearForm, + }, + ]; +} \ No newline at end of file diff --git a/src/lib/components/patient/modal/custodian-modal.svelte b/src/lib/components/patient/modal/custodian-modal.svelte new file mode 100644 index 0000000..2801fb1 --- /dev/null +++ b/src/lib/components/patient/modal/custodian-modal.svelte @@ -0,0 +1,157 @@ + + +{#snippet Fieldset({ key, label, type })} + {#if type === "text"} +
+
+ +
+
+ +
+
+ {:else if type === "date"} + + {/if} +{/snippet} + + + + + + + + Search Custodian + +
+
+
+ {#each searchFields as field} + {@render Fieldset(field)} + {/each} +
+
+
+ + +
+
+
+ {#if search.searchData.length === 0} +
+ +
+ {:else} + + + + + Patient ID + Patient Name + Birthdate + Sex + + + + {#each search.searchData as patient, i} + togglePatientSelection(patient)} + > + + togglePatientSelection(patient)} + /> + + {patient.PatientID} + {patient.FullName} + {patient.Birthdate ? patient.Birthdate.split(" ")[0] : ""} + {patient.Gender} + + {/each} + + + {/if} +
+ + + +
+
\ No newline at end of file diff --git a/src/lib/components/patient/modal/linkto-modal.svelte b/src/lib/components/patient/modal/linkto-modal.svelte new file mode 100644 index 0000000..9703cf4 --- /dev/null +++ b/src/lib/components/patient/modal/linkto-modal.svelte @@ -0,0 +1,286 @@ + + +{#snippet Fieldset({ key, label, type })} + {#if type === "text"} +
+
+ +
+
+ +
+
+ {:else if type === "date"} + + {/if} +{/snippet} + + + + + + + + Link Patients + {#if selectedPatients.length > 0} +

+ {selectedPatients.length} patient{selectedPatients.length > 1 ? 's' : ''} selected +

+ {/if} +
+ +
+
+
+ {#each searchFields as field} + {@render Fieldset(field)} + {/each} +
+
+ +
+ + +
+
+ +
+ {#if search.searchData.length === 0} +
+ +
+ {:else} + + + + + Patient ID + Patient Name + Birthdate + Sex + + + + {#each search.searchData as patient} + togglePatientSelection(patient)} + > + e.stopPropagation()}> + togglePatientSelection(patient)} + /> + + {patient.PatientID} + {patient.FullName} + + {patient.Birthdate ? patient.Birthdate.split(" ")[0] : ""} + + {patient.Gender} + + {/each} + + + {/if} +
+ + + + +
+
+ + \ No newline at end of file diff --git a/src/lib/components/patient/page/create-page copy.svelte b/src/lib/components/patient/page/create-page copy.svelte new file mode 100644 index 0000000..3761adc --- /dev/null +++ b/src/lib/components/patient/page/create-page copy.svelte @@ -0,0 +1,403 @@ + + + + + + + + \ No newline at end of file diff --git a/src/lib/components/patient/page/create-page.svelte b/src/lib/components/patient/page/create-page.svelte new file mode 100644 index 0000000..cc42426 --- /dev/null +++ b/src/lib/components/patient/page/create-page.svelte @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/patient/page/edit-page.svelte b/src/lib/components/patient/page/edit-page.svelte new file mode 100644 index 0000000..1cb592d --- /dev/null +++ b/src/lib/components/patient/page/edit-page.svelte @@ -0,0 +1,523 @@ + + +{#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, validateOn, dependsOn, endpointParamKey })} +
+
+ + {#if required} + * + {/if} +
+ +
+ {#if type === "input" || type === "email" || type === "number"} + { + if (validateOn?.includes("input")) { + formState.validateField(key); + } + }} + onblur={() => { + if (validateOn?.includes("blur")) { + validateFieldAsync(key); + } + }} + /> + {:else if type === "date"} + { + formState.form[key] = dateStr; + if (validateOn?.includes("input")) { + formState.validateField(key, dateStr, false); + } + }} + /> + {:else if type === "datetime"} + + + {:else if type === "textarea"} + + {:else if type === "select"} + {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form[key])?.label || "Choose"} + {@const filteredOptions = getFilteredOptions(key)} + { + formState.form[key] = val; + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + if (key === "Province") { + formState.form.City = ""; + formState.selectOptions.City = []; + formState.lastFetched.City = null; + } + }} + onOpenChange={(open) => { + if (open && optionsEndpoint) { + formState.fetchOptions({ key, optionsEndpoint, dependsOn, endpointParamKey}, formState.form ); + } + }} + > + + {selectedLabel} + + +
+ +
+ {#if formState.loadingOptions[key]} + Loading... + {:else} + {#if !required} + - None - + {/if} + {#each filteredOptions as option} + + {option.label} + + {/each} + {/if} +
+
+ {:else if type === "identity"} + {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form.PatIdt.IdentifierType)?.label || "Choose"} +
+ { + if (open && optionsEndpoint) { + formState.fetchOptions({ key, optionsEndpoint}); + } + }} + onValueChange={(val) => { + formState.form.PatIdt = { + IdentifierType: val, + Identifier:'' + }; + }} + > + + {selectedLabel} + + + {#if formState.loadingOptions[key]} + Loading... + {:else} + {#if !required} + - None - + {/if} + {#each formState.selectOptions[key] ?? [] as option} + + {option.label} + + {/each} + {/if} + + + +
+ {:else if type === "custodian"} +
+ + +
+ {:else if type === "linkto"} +
+ + +
+ {:else if type === "fileupload"} +
+ + {#if Object.keys(uploadErrors).length > 0} +
+ {#each Object.entries(uploadErrors) as [file, msg]} + {msg} + {/each} +
+ {/if} +
+ {:else} + + {/if} + +
+ + {#if isChecking[key]} +
+ + Checking... +
+ {:else if formState.errors[key]} + + {formState.errors[key]} + + {/if} +
+
+
+{/snippet} + + +
+ {#each patientFormFields as group} +
+ {#if group.title} +
+ {group.title} +
+ {/if} + + {#each group.rows as row} +
+ {#each row.columns as col} + {#if col.type === "group"} +
+ {#each col.columns as child} + {@render Fieldset(child)} + {/each} +
+ {:else} + {@render Fieldset(col)} + {/if} + {/each} +
+ {/each} +
+ {/each} +
+
+ + \ No newline at end of file diff --git a/src/lib/components/patient/page/master-page.svelte b/src/lib/components/patient/page/master-page.svelte new file mode 100644 index 0000000..82cf151 --- /dev/null +++ b/src/lib/components/patient/page/master-page.svelte @@ -0,0 +1,63 @@ + + +{#snippet searchParamSnippet()} + +{/snippet} + +
props.masterDetail.isFormMode && props.masterDetail.exitForm()} + onkeydown={(e) => e.key === 'Enter' && props.masterDetail.isFormMode && props.masterDetail.exitForm()} + class={` + ${props.masterDetail.isMobile ? "w-full" : props.masterDetail.isFormMode ? "w-[3%] cursor-pointer" : "w-[35%]"} + transition-all duration-300 flex flex-col items-center p-2 h-full overflow-y-auto + `} +> +
+ {#if props.masterDetail.isFormMode} + + {#each "PATIENT".split("") as c} + {c} + {/each} + + {/if} + + {#if !props.masterDetail.isFormMode} +
e.stopPropagation()} onkeydown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + e.stopPropagation(); + } + }}> + +
+ {#if search.searchData.length > 0} + + {:else} +
+ +
+ {/if} +
+
+ {/if} +
+
\ No newline at end of file diff --git a/src/lib/components/patient/page/view-page.svelte b/src/lib/components/patient/page/view-page.svelte new file mode 100644 index 0000000..9d4d9d6 --- /dev/null +++ b/src/lib/components/patient/page/view-page.svelte @@ -0,0 +1,123 @@ + + +{#snippet Fieldset({ value, label, className = '', isUTCDate = false, isFileList = false })} +
+
+ {label} +
+
+ {#if isFileList && Array.isArray(value)} + + {:else if Array.isArray(value)} + {#each value as item, i} + {item.PatientID || item.Identifier || JSON.stringify(item)}{i < value.length - 1 ? ', ' : ''} + {/each} + {:else if isUTCDate} + {formatUTCDate(value)} + {:else} + {value ?? "-"} + {/if} +
+
+{/snippet} + +{#if props.masterDetail.selectedItem} +
+ +
+ {#each detailSections as section} +
+
+ {#each section.fields as field} + {#if field.isGroup} +
+ {#each field.fields as subField} + {@render Fieldset({ + label: subField.label, + value: getFieldValue(subField) + })} + {/each} +
+ {:else} + {@render Fieldset({ + label: field.label, + value: getFieldValue(field), + className: field.className, + isUTCDate: field.isUTCDate, + isFileList: field.isFileList + })} + {/if} + {/each} +
+
+ {/each} +
+
+{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/patient/reusable/form-page-container.svelte b/src/lib/components/patient/reusable/form-page-container.svelte new file mode 100644 index 0000000..0545273 --- /dev/null +++ b/src/lib/components/patient/reusable/form-page-container.svelte @@ -0,0 +1,82 @@ + + +
+ + {@render children()} +
+ + {#if secondaryActions.length} + + + + + + + + {#each secondaryActions as action} + + {action.label} + + {/each} + + + + {/if} + +
+
\ No newline at end of file diff --git a/src/lib/components/patient/reusable/patient-form-renderer.svelte b/src/lib/components/patient/reusable/patient-form-renderer.svelte new file mode 100644 index 0000000..d150db3 --- /dev/null +++ b/src/lib/components/patient/reusable/patient-form-renderer.svelte @@ -0,0 +1,334 @@ + + +{#snippet Fieldset({ key, label, required, type, optionsEndpoint, options, validateOn, dependsOn, endpointParamKey })} +
+
+ + {#if required} + * + {/if} +
+ +
+ {#if type === "text"} + { + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + }} + onblur={() => { + if (validateOn?.includes("blur")) { + validateFieldAsync(key); + } + }} + /> + {:else if type === "email"} + { + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + }} + onblur={() => { + if (validateOn?.includes("blur")) { + formState.validateField(key, formState.form[key], false); + } + }} + /> + {:else if type === "number"} + { + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + }} + onblur={() => { + if (validateOn?.includes("blur")) { + formState.validateField(key, formState.form[key], false); + } + }} + /> + {:else if type === "date"} + { + formState.form[key] = dateStr; + if (validateOn?.includes("input")) { + formState.validateField(key, dateStr, false); + } + }} + /> + {:else if type === "datetime"} + { + formState.form[key] = val; + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + }} + /> + {:else if type === "textarea"} + + {:else if type === "select"} + {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form[key])?.label || "Choose"} + {@const filteredOptions = getFilteredOptions(key)} + { + formState.form[key] = val; + if (validateOn?.includes("input")) { + formState.validateField(key, formState.form[key], false); + } + if (key === "Province") { + formState.form.City = ""; + formState.selectOptions.City = []; + formState.lastFetched.City = null; + } + }} + onOpenChange={(open) => { + if (open && optionsEndpoint) { + formState.fetchOptions( + { key, optionsEndpoint, dependsOn, endpointParamKey }, + formState.form + ); + } + }} + > + + {selectedLabel} + + +
+ +
+ {#if formState.loadingOptions[key]} + Loading... + {:else} + {#if !required} + - None - + {/if} + {#each filteredOptions as option} + + {option.label} + + {/each} + {/if} +
+
+ {:else if type === "identity"} + {@const selectedLabel = formState.selectOptions[key]?.find(opt => opt.value === formState.form.PatIdt.IdentifierType)?.label || "Choose"} +
+ { + if (open && optionsEndpoint) { + formState.fetchOptions({ key, optionsEndpoint}); + } + }} + onValueChange={(val) => { + formState.form.PatIdt = { + IdentifierType: val, + Identifier:'' + }; + }} + > + + {selectedLabel} + + + {#if formState.loadingOptions[key]} + Loading... + {:else} + {#if !required} + - None - + {/if} + {#each formState.selectOptions[key] ?? [] as option} + + {option.label} + + {/each} + {/if} + + + +
+ {:else if type === "custodian"} +
+ + +
+ {:else if type === "linkto"} +
+ + +
+ {:else if type === "fileupload"} +
+ + {#if Object.keys(uploadErrors).length > 0} +
+ {#each Object.entries(uploadErrors) as [file, msg]} + {msg} + {/each} +
+ {/if} +
+ {:else} + + {/if} + +
+ {#if isChecking[key]} +
+ + Checking... +
+ {:else if formState.errors[key]} + + {formState.errors[key]} + + {/if} +
+
+
+{/snippet} + +
+ {#each formFields as group} +
+ {#if group.title} +
+ {group.title} +
+ {/if} + + {#each group.rows as row} +
+ {#each row.columns as col} + {#if col.type === "group"} +
+ {#each col.columns as child} + {@render Fieldset(child)} + {/each} +
+ {:else} + {@render Fieldset(col)} + {/if} + {/each} +
+ {/each} +
+ {/each} +
\ No newline at end of file diff --git a/src/lib/components/patient/table/colums.js b/src/lib/components/patient/table/colums.js new file mode 100644 index 0000000..3d94c62 --- /dev/null +++ b/src/lib/components/patient/table/colums.js @@ -0,0 +1,23 @@ +export const columns = [ + { + accessorKey: "PatientID", + header: "PatientID", + }, + { + accessorKey: "FullName", + header: "Patient Name", + }, + { + accessorKey: "SexLabel", + header: "Sex", + }, + { + accessorKey: "Birthdate", + header: "Birthdate", + cell: ({ getValue }) => { + const value = getValue(); + if (!value) return ""; + return value.split(' ')[0]; + } + }, +]; \ No newline at end of file diff --git a/src/lib/components/reusable/reusable-calendar-timepicker.svelte b/src/lib/components/reusable/reusable-calendar-timepicker.svelte new file mode 100644 index 0000000..18c53c2 --- /dev/null +++ b/src/lib/components/reusable/reusable-calendar-timepicker.svelte @@ -0,0 +1,196 @@ + + +
+ {#if title} + + {/if} + + + {#snippet child({ props })} + + {/snippet} + + +
+ +
+
+
+ +
+ + +
+
+
+
+
+
+ + diff --git a/src/lib/components/reusable/reusable-calendar.svelte b/src/lib/components/reusable/reusable-calendar.svelte new file mode 100644 index 0000000..8bb204b --- /dev/null +++ b/src/lib/components/reusable/reusable-calendar.svelte @@ -0,0 +1,71 @@ + + +
+ {#if title} + + {/if} + + + {#snippet child({ props })} + + {/snippet} + + + + + +
\ No newline at end of file diff --git a/src/lib/components/reusable/reusable-data-table.svelte b/src/lib/components/reusable/reusable-data-table.svelte new file mode 100644 index 0000000..5400507 --- /dev/null +++ b/src/lib/components/reusable/reusable-data-table.svelte @@ -0,0 +1,187 @@ + +
+
+ { + globalFilter = e.currentTarget.value; + }} + class="h-8 w-64 text-xs px-2" + /> +
+
+ + + {#each table.getHeaderGroups() as headerGroup (headerGroup.id)} + + {#each headerGroup.headers as header (header.id)} + + {#if !header.isPlaceholder} + + {/if} + + {/each} + + {/each} + + + {#each table.getRowModel().rows as row (row.id)} + props.handleRowClick(row.original)} + class="cursor-pointer" + > + {#each row.getVisibleCells() as cell, i (cell.id)} + + + + {/each} + + {:else} + + + No results. + + + {/each} + + +
+
+

Rows per page

+ { + table.setPageSize(Number(value)); + }} + > + + {String(table.getState().pagination.pageSize)} + + + {#each [1, 2, 3, 4, 5] as pageSize (pageSize)} + + {pageSize} + + {/each} + + +
+
+
+ Page {table.getState().pagination.pageIndex + 1} of + {table.getPageCount()} +
+
+ + + + +
+
+
+
+ +
\ No newline at end of file diff --git a/src/lib/components/reusable/reusable-empty.svelte b/src/lib/components/reusable/reusable-empty.svelte new file mode 100644 index 0000000..85b4736 --- /dev/null +++ b/src/lib/components/reusable/reusable-empty.svelte @@ -0,0 +1,19 @@ + + + + + + {#if Icon} + + {/if} + + {props.title ?? "No Data"} + {props.desc ?? "No Data"} + + \ No newline at end of file diff --git a/src/lib/components/reusable/reusable-search-param.svelte b/src/lib/components/reusable/reusable-search-param.svelte new file mode 100644 index 0000000..637ada3 --- /dev/null +++ b/src/lib/components/reusable/reusable-search-param.svelte @@ -0,0 +1,53 @@ + + +
+
+ {#each props.searchFields as field} + {#if field.type === "text"} +
+ + +
+ {:else if field.type === "date"} +
+ +
+ {:else if field.type === "select"} +
+ + + + + + + {#each field.options as opt} + + {opt.label} + + {/each} + + +
+ {/if} + {/each} +
+
+ + +
+
\ No newline at end of file diff --git a/src/lib/components/reusable/reusable-upload.svelte b/src/lib/components/reusable/reusable-upload.svelte new file mode 100644 index 0000000..e63b5e3 --- /dev/null +++ b/src/lib/components/reusable/reusable-upload.svelte @@ -0,0 +1,277 @@ + + + + + + + +
+
+ {#if attachments.length > 0} +
+

Uploaded

+ {#each attachments as item, i} +
+
+ +
+
+

+ {item.Address.split("/").pop()} +

+
+ +
+ {/each} +
+ {/if} + {#if files.length > 0} +
+

To be uploaded

+ {#each files as item, i} +
+
+
+ +
+
+

+ {item.file.name} +

+ {#if item.uploading} +
+
+
+
+

{item.progress}%

+
+ {/if} +
+
+ {#if item.uploaded} +
+ + + +
+ {:else if item.uploading} + + {:else if item.error} + + {:else} + + {/if} + {#if !item.uploaded && !item.uploading} + + {/if} +
+
+
+ {/each} +
+ {/if} + {#if attachments.length === 0 && files.length === 0} +
+ +
+ {/if} +
+
+ +
+
+
+
\ No newline at end of file diff --git a/src/lib/components/topbar/topbar-action.svelte b/src/lib/components/topbar/topbar-action.svelte new file mode 100644 index 0000000..b46b515 --- /dev/null +++ b/src/lib/components/topbar/topbar-action.svelte @@ -0,0 +1,51 @@ + + + + + + {#snippet child({ props: tooltipProps })} + {#if props.popoverContent} + + + {#snippet child({ props: popoverProps })} + + {/snippet} + + + {@render props.popoverContent()} + + + {:else} + + {/if} + {/snippet} + + +

{props.label}

+
+
+
\ No newline at end of file diff --git a/src/lib/components/topbar/topbar-wrapper.svelte b/src/lib/components/topbar/topbar-wrapper.svelte new file mode 100644 index 0000000..48afa3e --- /dev/null +++ b/src/lib/components/topbar/topbar-wrapper.svelte @@ -0,0 +1,19 @@ + + +
+

+ {props.title} + {#if props.subtitle} + ,({props.subtitle}) + {/if} +

+
+ {#each props.actions ?? [] as action} + + {/each} +
+
\ No newline at end of file diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..f43a6e8 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..bffa5b8 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..89c661f --- /dev/null +++ b/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/avatar/index.js b/src/lib/components/ui/avatar/index.js new file mode 100644 index 0000000..a6bea46 --- /dev/null +++ b/src/lib/components/ui/avatar/index.js @@ -0,0 +1,13 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; + +export { + Root, + Image, + Fallback, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback, +}; \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte new file mode 100644 index 0000000..359a09e --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte new file mode 100644 index 0000000..ad42eff --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte @@ -0,0 +1,19 @@ + + +
  • + {@render children?.()} +
  • \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte new file mode 100644 index 0000000..f5705ff --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte @@ -0,0 +1,27 @@ + + +{#if child} + {@render child({ props: attrs })} +{:else} + + {@render children?.()} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte new file mode 100644 index 0000000..1679f86 --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte @@ -0,0 +1,22 @@ + + +
      + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte new file mode 100644 index 0000000..56bb39e --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte @@ -0,0 +1,22 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte new file mode 100644 index 0000000..1d6a8e2 --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/src/lib/components/ui/breadcrumb/breadcrumb.svelte new file mode 100644 index 0000000..6f81cfd --- /dev/null +++ b/src/lib/components/ui/breadcrumb/breadcrumb.svelte @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/breadcrumb/index.js b/src/lib/components/ui/breadcrumb/index.js new file mode 100644 index 0000000..255577f --- /dev/null +++ b/src/lib/components/ui/breadcrumb/index.js @@ -0,0 +1,25 @@ +import Root from "./breadcrumb.svelte"; +import Ellipsis from "./breadcrumb-ellipsis.svelte"; +import Item from "./breadcrumb-item.svelte"; +import Separator from "./breadcrumb-separator.svelte"; +import Link from "./breadcrumb-link.svelte"; +import List from "./breadcrumb-list.svelte"; +import Page from "./breadcrumb-page.svelte"; + +export { + Root, + Ellipsis, + Item, + Separator, + Link, + List, + Page, + // + Root as Breadcrumb, + Ellipsis as BreadcrumbEllipsis, + Item as BreadcrumbItem, + Separator as BreadcrumbSeparator, + Link as BreadcrumbLink, + List as BreadcrumbList, + Page as BreadcrumbPage, +}; \ No newline at end of file diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..2b0473f --- /dev/null +++ b/src/lib/components/ui/button/button.svelte @@ -0,0 +1,73 @@ + + + + +{#if href} + + {@render children?.()} + +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/button/index.js b/src/lib/components/ui/button/index.js new file mode 100644 index 0000000..9d66568 --- /dev/null +++ b/src/lib/components/ui/button/index.js @@ -0,0 +1,13 @@ +import Root, { + + buttonVariants, +} from "./button.svelte"; + +export { + Root, + + // + Root as Button, + buttonVariants, + +}; \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-caption.svelte b/src/lib/components/ui/calendar/calendar-caption.svelte new file mode 100644 index 0000000..e643e11 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-caption.svelte @@ -0,0 +1,64 @@ + + +{#snippet MonthSelect()} + { + if (!placeholder) return; + const v = Number.parseInt(e.currentTarget.value); + const newPlaceholder = placeholder.set({ month: v }); + placeholder = newPlaceholder.subtract({ months: monthIndex }); + }} + /> +{/snippet} + +{#snippet YearSelect()} + +{/snippet} + +{#if captionLayout === "dropdown"} + {@render MonthSelect()} + {@render YearSelect()} +{:else if captionLayout === "dropdown-months"} + {@render MonthSelect()} + {#if placeholder} + {formatYear(placeholder)} + {/if} +{:else if captionLayout === "dropdown-years"} + {#if placeholder} + {formatMonth(placeholder)} + {/if} + {@render YearSelect()} +{:else} + {formatMonth(month)} {formatYear(month)} +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-cell.svelte b/src/lib/components/ui/calendar/calendar-cell.svelte new file mode 100644 index 0000000..c108a3c --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-cell.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-day.svelte b/src/lib/components/ui/calendar/calendar-day.svelte new file mode 100644 index 0000000..f4640ab --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-day.svelte @@ -0,0 +1,35 @@ + + +span]:text-xs [&>span]:opacity-70", + className + )} + {...restProps} +/> \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-grid-body.svelte b/src/lib/components/ui/calendar/calendar-grid-body.svelte new file mode 100644 index 0000000..094cbd7 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-body.svelte @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-grid-head.svelte b/src/lib/components/ui/calendar/calendar-grid-head.svelte new file mode 100644 index 0000000..da10c38 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-head.svelte @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-grid-row.svelte b/src/lib/components/ui/calendar/calendar-grid-row.svelte new file mode 100644 index 0000000..167e3c8 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid-row.svelte @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-grid.svelte b/src/lib/components/ui/calendar/calendar-grid.svelte new file mode 100644 index 0000000..1cdb0ca --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-grid.svelte @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-head-cell.svelte b/src/lib/components/ui/calendar/calendar-head-cell.svelte new file mode 100644 index 0000000..682a6ae --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-head-cell.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-header.svelte b/src/lib/components/ui/calendar/calendar-header.svelte new file mode 100644 index 0000000..645f1f2 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-header.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-heading.svelte b/src/lib/components/ui/calendar/calendar-heading.svelte new file mode 100644 index 0000000..5d01272 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-heading.svelte @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-month-select.svelte b/src/lib/components/ui/calendar/calendar-month-select.svelte new file mode 100644 index 0000000..cc28340 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-month-select.svelte @@ -0,0 +1,44 @@ + + + + + {#snippet child({ props, monthItems, selectedMonthItem })} + + + {/snippet} + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-month.svelte b/src/lib/components/ui/calendar/calendar-month.svelte new file mode 100644 index 0000000..8e62ef9 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-month.svelte @@ -0,0 +1,13 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-months.svelte b/src/lib/components/ui/calendar/calendar-months.svelte new file mode 100644 index 0000000..9e2d132 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-months.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-nav.svelte b/src/lib/components/ui/calendar/calendar-nav.svelte new file mode 100644 index 0000000..d012212 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-nav.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-next-button.svelte b/src/lib/components/ui/calendar/calendar-next-button.svelte new file mode 100644 index 0000000..83da470 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-next-button.svelte @@ -0,0 +1,29 @@ + + +{#snippet Fallback()} + +{/snippet} + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-prev-button.svelte b/src/lib/components/ui/calendar/calendar-prev-button.svelte new file mode 100644 index 0000000..455b904 --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-prev-button.svelte @@ -0,0 +1,29 @@ + + +{#snippet Fallback()} + +{/snippet} + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar-year-select.svelte b/src/lib/components/ui/calendar/calendar-year-select.svelte new file mode 100644 index 0000000..df7d65e --- /dev/null +++ b/src/lib/components/ui/calendar/calendar-year-select.svelte @@ -0,0 +1,43 @@ + + + + + {#snippet child({ props, yearItems, selectedYearItem })} + + + {/snippet} + + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/calendar.svelte b/src/lib/components/ui/calendar/calendar.svelte new file mode 100644 index 0000000..828df9b --- /dev/null +++ b/src/lib/components/ui/calendar/calendar.svelte @@ -0,0 +1,104 @@ + + + + + {#snippet children({ months, weekdays })} + + + + + + {#each months as month, monthIndex (month)} + + + + + + + + {#each weekdays as weekday (weekday)} + + {weekday.slice(0, 2)} + + {/each} + + + + {#each month.weeks as weekDates (weekDates)} + + {#each weekDates as date (date)} + + {#if day} + {@render day({ + day: date, + outsideMonth: !isEqualMonth(date, month.value), + })} + {:else} + + {/if} + + {/each} + + {/each} + + + + {/each} + + {/snippet} + \ No newline at end of file diff --git a/src/lib/components/ui/calendar/index.js b/src/lib/components/ui/calendar/index.js new file mode 100644 index 0000000..cc77754 --- /dev/null +++ b/src/lib/components/ui/calendar/index.js @@ -0,0 +1,40 @@ +import Root from "./calendar.svelte"; +import Cell from "./calendar-cell.svelte"; +import Day from "./calendar-day.svelte"; +import Grid from "./calendar-grid.svelte"; +import Header from "./calendar-header.svelte"; +import Months from "./calendar-months.svelte"; +import GridRow from "./calendar-grid-row.svelte"; +import Heading from "./calendar-heading.svelte"; +import GridBody from "./calendar-grid-body.svelte"; +import GridHead from "./calendar-grid-head.svelte"; +import HeadCell from "./calendar-head-cell.svelte"; +import NextButton from "./calendar-next-button.svelte"; +import PrevButton from "./calendar-prev-button.svelte"; +import MonthSelect from "./calendar-month-select.svelte"; +import YearSelect from "./calendar-year-select.svelte"; +import Month from "./calendar-month.svelte"; +import Nav from "./calendar-nav.svelte"; +import Caption from "./calendar-caption.svelte"; + +export { + Day, + Cell, + Grid, + Header, + Months, + GridRow, + Heading, + GridBody, + GridHead, + HeadCell, + NextButton, + PrevButton, + Nav, + Month, + YearSelect, + MonthSelect, + Caption, + // + Root as Calendar, +}; \ No newline at end of file diff --git a/src/lib/components/ui/card/card-action.svelte b/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..9d01cc3 --- /dev/null +++ b/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..f75ecad --- /dev/null +++ b/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,14 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..0b16249 --- /dev/null +++ b/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,19 @@ + + +

    + {@render children?.()} +

    \ No newline at end of file diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..21ad7bf --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..a01f64c --- /dev/null +++ b/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..9bc0c1a --- /dev/null +++ b/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..78953d4 --- /dev/null +++ b/src/lib/components/ui/card/card.svelte @@ -0,0 +1,22 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/card/index.js b/src/lib/components/ui/card/index.js new file mode 100644 index 0000000..210f6f3 --- /dev/null +++ b/src/lib/components/ui/card/index.js @@ -0,0 +1,25 @@ +import Root from "./card.svelte"; +import Content from "./card-content.svelte"; +import Description from "./card-description.svelte"; +import Footer from "./card-footer.svelte"; +import Header from "./card-header.svelte"; +import Title from "./card-title.svelte"; +import Action from "./card-action.svelte"; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + Action, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, + Action as CardAction, +}; \ No newline at end of file diff --git a/src/lib/components/ui/checkbox/checkbox.svelte b/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..331071a --- /dev/null +++ b/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,36 @@ + + + + {#snippet children({ checked, indeterminate })} +
    + {#if checked} + + {:else if indeterminate} + + {/if} +
    + {/snippet} +
    \ No newline at end of file diff --git a/src/lib/components/ui/checkbox/index.js b/src/lib/components/ui/checkbox/index.js new file mode 100644 index 0000000..420b3d3 --- /dev/null +++ b/src/lib/components/ui/checkbox/index.js @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; \ No newline at end of file diff --git a/src/lib/components/ui/collapsible/collapsible-content.svelte b/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..a424df2 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..8d8e207 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/collapsible/collapsible.svelte b/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..a115caa --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/collapsible/index.js b/src/lib/components/ui/collapsible/index.js new file mode 100644 index 0000000..4d68713 --- /dev/null +++ b/src/lib/components/ui/collapsible/index.js @@ -0,0 +1,13 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; \ No newline at end of file diff --git a/src/lib/components/ui/data-table/data-table.svelte.js b/src/lib/components/ui/data-table/data-table.svelte.js new file mode 100644 index 0000000..cf5770b --- /dev/null +++ b/src/lib/components/ui/data-table/data-table.svelte.js @@ -0,0 +1,134 @@ +import { + + createTable, +} from "@tanstack/table-core"; + +/** + * Creates a reactive TanStack table object for Svelte. + * @param options Table options to create the table with. + * @returns A reactive table object. + * @example + * ```svelte + * + * + * + * + * {#each table.getHeaderGroups() as headerGroup} + * + * {#each headerGroup.headers as header} + * + * {/each} + * + * {/each} + * + * + *
    + * + *
    + * ``` + */ +export function createSvelteTable(options) { + const resolvedOptions = mergeObjects( + { + state: {}, + onStateChange() {}, + renderFallbackValue: null, + mergeOptions: ( + defaultOptions, + options + ) => { + return mergeObjects(defaultOptions, options); + }, + }, + options + ); + + const table = createTable(resolvedOptions); + let state = $state(table.initialState); + + function updateOptions() { + table.setOptions((prev) => { + return mergeObjects(prev, options, { + state: mergeObjects(state, options.state || {}), + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onStateChange: (updater) => { + if (updater instanceof Function) state = updater(state); + else state = mergeObjects(state, updater); + + options.onStateChange?.(updater); + }, + }); + }); + } + + updateOptions(); + + $effect.pre(() => { + updateOptions(); + }); + + return table; +} + +/** + * Lazily merges several objects (or thunks) while preserving + * getter semantics from every source. + * + * Proxy-based to avoid known WebKit recursion issue. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function mergeObjects( + ...sources +) { + const resolve = (src) => + typeof src === "function" ? (src() ?? undefined) : src; + + const findSourceWithKey = (key) => { + for (let i = sources.length - 1; i >= 0; i--) { + const obj = resolve(sources[i]); + if (obj && key in obj) return obj; + } + return undefined; + }; + + return new Proxy(Object.create(null), { + get(_, key) { + const src = findSourceWithKey(key); + + return src?.[key ]; + }, + + has(_, key) { + return !!findSourceWithKey(key); + }, + + ownKeys() { + // eslint-disable-next-line svelte/prefer-svelte-reactivity + const all = new Set(); + for (const s of sources) { + const obj = resolve(s); + if (obj) { + for (const k of Reflect.ownKeys(obj) ) { + all.add(k); + } + } + } + return [...all]; + }, + + getOwnPropertyDescriptor(_, key) { + const src = findSourceWithKey(key); + if (!src) return undefined; + return { + configurable: true, + enumerable: true, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + value: (src )[key], + writable: true, + }; + }, + }) ; +} \ No newline at end of file diff --git a/src/lib/components/ui/data-table/flex-render.svelte b/src/lib/components/ui/data-table/flex-render.svelte new file mode 100644 index 0000000..881e7ad --- /dev/null +++ b/src/lib/components/ui/data-table/flex-render.svelte @@ -0,0 +1,24 @@ + + +{#if typeof content === "string"} + {content} +{:else if content instanceof Function} + + + {@const result = content(context)} + {#if result instanceof RenderComponentConfig} + {@const { component: Component, props } = result} + + {:else if result instanceof RenderSnippetConfig} + {@const { snippet, params } = result} + {@render snippet({ ...params, attach })} + {:else} + {result} + {/if} +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/data-table/index.js b/src/lib/components/ui/data-table/index.js new file mode 100644 index 0000000..6af11e8 --- /dev/null +++ b/src/lib/components/ui/data-table/index.js @@ -0,0 +1,3 @@ +export { default as FlexRender } from "./flex-render.svelte"; +export { renderComponent, renderSnippet } from "./render-helpers.js"; +export { createSvelteTable } from "./data-table.svelte.js"; \ No newline at end of file diff --git a/src/lib/components/ui/data-table/render-helpers.js b/src/lib/components/ui/data-table/render-helpers.js new file mode 100644 index 0000000..292785e --- /dev/null +++ b/src/lib/components/ui/data-table/render-helpers.js @@ -0,0 +1,107 @@ +/** + * A helper class to make it easy to identify Svelte components in + * `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderComponentConfig} + * {@const { component: Component, props } = result} + * + * {/if} + * ``` + */ +export class RenderComponentConfig { + component; + props; + constructor( + component, + props = {} + ) { + this.component = component; + this.props = props; + } +} + +/** + * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. + * + * > NOTE: This class should only be used internally by the adapter. If you're + * reading this and you don't know what this is for, you probably don't need it. + * + * @example + * ```svelte + * {@const result = content(context as any)} + * {#if result instanceof RenderSnippetConfig} + * {@const { snippet, params } = result} + * {@render snippet(params)} + * {/if} + * ``` + */ +export class RenderSnippetConfig { + snippet; + params; + constructor(snippet, params) { + this.snippet = snippet; + this.params = params; + } +} + +/** + * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. + * + * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. + * + * @param component A Svelte component + * @param props The props to pass to `component` + * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * header: header => renderComponent(SortHeader, { label: 'Name', header }), + * }), + * columnHelper.accessor('state', { + * header: header => renderComponent(SortHeader, { label: 'State', header }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderComponent + +(component, props = {} ) { + return new RenderComponentConfig(component, props); +} + +/** + * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. + * + * The snippet must only take one parameter. + * + * This is only to be used with Snippets - use `renderComponent` for Svelte Components. + * + * @param snippet + * @param params + * @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet. + * @example + * ```ts + * // +page.svelte + * const defaultColumns = [ + * columnHelper.accessor('name', { + * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), + * }), + * columnHelper.accessor('state', { + * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), + * }), + * ] + * ``` + * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} + */ +export function renderSnippet(snippet, params = {} ) { + return new RenderSnippetConfig(snippet, params); +} \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-close.svelte b/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..94266a6 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-content.svelte b/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..f9b420b --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,38 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + + Close + + {/if} + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-description.svelte b/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..419a27e --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-footer.svelte b/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..b2d4035 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-header.svelte b/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..2d4d36e --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-overlay.svelte b/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..adb8a38 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-portal.svelte b/src/lib/components/ui/dialog/dialog-portal.svelte new file mode 100644 index 0000000..2f418e9 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-title.svelte b/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..be9bf3f --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog-trigger.svelte b/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..7a38ff9 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/dialog.svelte b/src/lib/components/ui/dialog/dialog.svelte new file mode 100644 index 0000000..d48b822 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dialog/index.js b/src/lib/components/ui/dialog/index.js new file mode 100644 index 0000000..4703a64 --- /dev/null +++ b/src/lib/components/ui/dialog/index.js @@ -0,0 +1,34 @@ +import Root from "./dialog.svelte"; +import Portal from "./dialog-portal.svelte"; +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 0000000..d422761 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..b87e4a1 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,39 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..6132142 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..86a43fe --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..4f3421f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..8be3860 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,24 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..f9f0094 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 0000000..e40bdfc --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..009a4dd --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..20971dd --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,33 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..4d02884 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..0da07e4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,19 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..ebdf6fc --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..565dca9 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,27 @@ + + + + {@render children?.()} + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 0000000..a8d648a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..720d196 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 0000000..aae0b44 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/dropdown-menu/index.js b/src/lib/components/ui/dropdown-menu/index.js new file mode 100644 index 0000000..3eb3087 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.js @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty-content.svelte b/src/lib/components/ui/empty/empty-content.svelte new file mode 100644 index 0000000..ec008d9 --- /dev/null +++ b/src/lib/components/ui/empty/empty-content.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty-description.svelte b/src/lib/components/ui/empty/empty-description.svelte new file mode 100644 index 0000000..73dd322 --- /dev/null +++ b/src/lib/components/ui/empty/empty-description.svelte @@ -0,0 +1,21 @@ + + +
    a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4", + className + )} + {...restProps} +> + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty-header.svelte b/src/lib/components/ui/empty/empty-header.svelte new file mode 100644 index 0000000..d640c93 --- /dev/null +++ b/src/lib/components/ui/empty/empty-header.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty-media.svelte b/src/lib/components/ui/empty/empty-media.svelte new file mode 100644 index 0000000..6225e7d --- /dev/null +++ b/src/lib/components/ui/empty/empty-media.svelte @@ -0,0 +1,37 @@ + + + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty-title.svelte b/src/lib/components/ui/empty/empty-title.svelte new file mode 100644 index 0000000..fc040c1 --- /dev/null +++ b/src/lib/components/ui/empty/empty-title.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/empty.svelte b/src/lib/components/ui/empty/empty.svelte new file mode 100644 index 0000000..5e31625 --- /dev/null +++ b/src/lib/components/ui/empty/empty.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/empty/index.js b/src/lib/components/ui/empty/index.js new file mode 100644 index 0000000..8121b79 --- /dev/null +++ b/src/lib/components/ui/empty/index.js @@ -0,0 +1,22 @@ +import Root from "./empty.svelte"; +import Header from "./empty-header.svelte"; +import Media from "./empty-media.svelte"; +import Title from "./empty-title.svelte"; +import Description from "./empty-description.svelte"; +import Content from "./empty-content.svelte"; + +export { + Root, + Header, + Media, + Title, + Description, + Content, + // + Root as Empty, + Header as EmptyHeader, + Media as EmptyMedia, + Title as EmptyTitle, + Description as EmptyDescription, + Content as EmptyContent, +}; \ No newline at end of file diff --git a/src/lib/components/ui/input/index.js b/src/lib/components/ui/input/index.js new file mode 100644 index 0000000..0750b46 --- /dev/null +++ b/src/lib/components/ui/input/index.js @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; \ No newline at end of file diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..3109c78 --- /dev/null +++ b/src/lib/components/ui/input/input.svelte @@ -0,0 +1,44 @@ + + +{#if type === "file"} + +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/label/index.js b/src/lib/components/ui/label/index.js new file mode 100644 index 0000000..6def9ee --- /dev/null +++ b/src/lib/components/ui/label/index.js @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; \ No newline at end of file diff --git a/src/lib/components/ui/label/label.svelte b/src/lib/components/ui/label/label.svelte new file mode 100644 index 0000000..d3d712c --- /dev/null +++ b/src/lib/components/ui/label/label.svelte @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/popover/index.js b/src/lib/components/ui/popover/index.js new file mode 100644 index 0000000..224ca9e --- /dev/null +++ b/src/lib/components/ui/popover/index.js @@ -0,0 +1,19 @@ +import Root from "./popover.svelte"; +import Close from "./popover-close.svelte"; +import Content from "./popover-content.svelte"; +import Trigger from "./popover-trigger.svelte"; +import Portal from "./popover-portal.svelte"; + +export { + Root, + Content, + Trigger, + Close, + Portal, + // + Root as Popover, + Content as PopoverContent, + Trigger as PopoverTrigger, + Close as PopoverClose, + Portal as PopoverPortal, +}; \ No newline at end of file diff --git a/src/lib/components/ui/popover/popover-close.svelte b/src/lib/components/ui/popover/popover-close.svelte new file mode 100644 index 0000000..2c9db17 --- /dev/null +++ b/src/lib/components/ui/popover/popover-close.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/popover/popover-content.svelte b/src/lib/components/ui/popover/popover-content.svelte new file mode 100644 index 0000000..46662dc --- /dev/null +++ b/src/lib/components/ui/popover/popover-content.svelte @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/ui/popover/popover-portal.svelte b/src/lib/components/ui/popover/popover-portal.svelte new file mode 100644 index 0000000..d4971f9 --- /dev/null +++ b/src/lib/components/ui/popover/popover-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/popover/popover-trigger.svelte b/src/lib/components/ui/popover/popover-trigger.svelte new file mode 100644 index 0000000..4dd286b --- /dev/null +++ b/src/lib/components/ui/popover/popover-trigger.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/popover/popover.svelte b/src/lib/components/ui/popover/popover.svelte new file mode 100644 index 0000000..07c7f9d --- /dev/null +++ b/src/lib/components/ui/popover/popover.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/radio-group/index.js b/src/lib/components/ui/radio-group/index.js new file mode 100644 index 0000000..a649d22 --- /dev/null +++ b/src/lib/components/ui/radio-group/index.js @@ -0,0 +1,10 @@ +import Root from "./radio-group.svelte"; +import Item from "./radio-group-item.svelte"; + +export { + Root, + Item, + // + Root as RadioGroup, + Item as RadioGroupItem, +}; \ No newline at end of file diff --git a/src/lib/components/ui/radio-group/radio-group-item.svelte b/src/lib/components/ui/radio-group/radio-group-item.svelte new file mode 100644 index 0000000..1be14ae --- /dev/null +++ b/src/lib/components/ui/radio-group/radio-group-item.svelte @@ -0,0 +1,31 @@ + + + + {#snippet children({ checked })} +
    + {#if checked} + + {/if} +
    + {/snippet} +
    \ No newline at end of file diff --git a/src/lib/components/ui/radio-group/radio-group.svelte b/src/lib/components/ui/radio-group/radio-group.svelte new file mode 100644 index 0000000..3174893 --- /dev/null +++ b/src/lib/components/ui/radio-group/radio-group.svelte @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/index.js b/src/lib/components/ui/select/index.js new file mode 100644 index 0000000..a3d99fb --- /dev/null +++ b/src/lib/components/ui/select/index.js @@ -0,0 +1,37 @@ +import Root from "./select.svelte"; +import Group from "./select-group.svelte"; +import Label from "./select-label.svelte"; +import Item from "./select-item.svelte"; +import Content from "./select-content.svelte"; +import Trigger from "./select-trigger.svelte"; +import Separator from "./select-separator.svelte"; +import ScrollDownButton from "./select-scroll-down-button.svelte"; +import ScrollUpButton from "./select-scroll-up-button.svelte"; +import GroupHeading from "./select-group-heading.svelte"; +import Portal from "./select-portal.svelte"; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + Portal, + // + Root as Select, + Group as SelectGroup, + Label as SelectLabel, + Item as SelectItem, + Content as SelectContent, + Trigger as SelectTrigger, + Separator as SelectSeparator, + ScrollDownButton as SelectScrollDownButton, + ScrollUpButton as SelectScrollUpButton, + GroupHeading as SelectGroupHeading, + Portal as SelectPortal, +}; \ No newline at end of file diff --git a/src/lib/components/ui/select/select-content.svelte b/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..12d505c --- /dev/null +++ b/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,40 @@ + + + + + + + {@render children?.()} + + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-group-heading.svelte b/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..cfb1dc0 --- /dev/null +++ b/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,19 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-group.svelte b/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 0000000..582623d --- /dev/null +++ b/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-item.svelte b/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..1f8bea7 --- /dev/null +++ b/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,38 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-label.svelte b/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 0000000..1b21a80 --- /dev/null +++ b/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/select/select-portal.svelte b/src/lib/components/ui/select/select-portal.svelte new file mode 100644 index 0000000..2e17277 --- /dev/null +++ b/src/lib/components/ui/select/select-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-scroll-down-button.svelte b/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..9dc327e --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-scroll-up-button.svelte b/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..3f119cf --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-separator.svelte b/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..37a047b --- /dev/null +++ b/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select-trigger.svelte b/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..ee86fbc --- /dev/null +++ b/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,27 @@ + + + + {@render children?.()} + + \ No newline at end of file diff --git a/src/lib/components/ui/select/select.svelte b/src/lib/components/ui/select/select.svelte new file mode 100644 index 0000000..4e39e3b --- /dev/null +++ b/src/lib/components/ui/select/select.svelte @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/separator/index.js b/src/lib/components/ui/separator/index.js new file mode 100644 index 0000000..51e3fd5 --- /dev/null +++ b/src/lib/components/ui/separator/index.js @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; \ No newline at end of file diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..dfa756e --- /dev/null +++ b/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/index.js b/src/lib/components/ui/sheet/index.js new file mode 100644 index 0000000..e0b171d --- /dev/null +++ b/src/lib/components/ui/sheet/index.js @@ -0,0 +1,34 @@ +import Root from "./sheet.svelte"; +import Portal from "./sheet-portal.svelte"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-close.svelte b/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 0000000..82c6945 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-content.svelte b/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..6dced16 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,51 @@ + + + + + + + + {@render children?.()} + + + Close + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-description.svelte b/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..3fc5fd7 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-footer.svelte b/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..9a6094a --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,18 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-header.svelte b/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..e3d3308 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-overlay.svelte b/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..6ef633d --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-portal.svelte b/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 0000000..dfc7f6d --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-title.svelte b/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..3955646 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet-trigger.svelte b/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 0000000..bc7fb36 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sheet/sheet.svelte b/src/lib/components/ui/sheet/sheet.svelte new file mode 100644 index 0000000..29a6cd1 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/constants.js b/src/lib/components/ui/sidebar/constants.js new file mode 100644 index 0000000..149d44b --- /dev/null +++ b/src/lib/components/ui/sidebar/constants.js @@ -0,0 +1,6 @@ +export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/context.svelte.js b/src/lib/components/ui/sidebar/context.svelte.js new file mode 100644 index 0000000..5461cda --- /dev/null +++ b/src/lib/components/ui/sidebar/context.svelte.js @@ -0,0 +1,63 @@ +import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; +import { getContext, setContext } from "svelte"; +import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; + +class SidebarState { + props; + open = $derived.by(() => this.props.open()); + openMobile = $state(false); + setOpen; + #isMobile; + state = $derived.by(() => (this.open ? "expanded" : "collapsed")); + + constructor(props) { + this.setOpen = props.setOpen; + this.#isMobile = new IsMobile(); + this.props = props; + } + + // Convenience getter for checking if the sidebar is mobile + // without this, we would need to use `sidebar.isMobile.current` everywhere + get isMobile() { + return this.#isMobile.current; + } + + // Event handler to apply to the `` + handleShortcutKeydown = (e) => { + if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + this.toggle(); + } + }; + + setOpenMobile = (value) => { + this.openMobile = value; + }; + + toggle = () => { + return this.#isMobile.current + ? (this.openMobile = !this.openMobile) + : this.setOpen(!this.open); + }; +} + +const SYMBOL_KEY = "scn-sidebar"; + +/** + * Instantiates a new `SidebarState` instance and sets it in the context. + * + * @param props The constructor props for the `SidebarState` class. + * @returns The `SidebarState` instance. + */ +export function setSidebar(props) { + return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); +} + +/** + * Retrieves the `SidebarState` instance from the context. This is a class instance, + * so you cannot destructure it. + * @returns The `SidebarState` instance. + */ +export function useSidebar() { + return getContext(Symbol.for(SYMBOL_KEY)); +} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/index.js b/src/lib/components/ui/sidebar/index.js new file mode 100644 index 0000000..e59e460 --- /dev/null +++ b/src/lib/components/ui/sidebar/index.js @@ -0,0 +1,75 @@ +import { useSidebar } from "./context.svelte.js"; +import Content from "./sidebar-content.svelte"; +import Footer from "./sidebar-footer.svelte"; +import GroupAction from "./sidebar-group-action.svelte"; +import GroupContent from "./sidebar-group-content.svelte"; +import GroupLabel from "./sidebar-group-label.svelte"; +import Group from "./sidebar-group.svelte"; +import Header from "./sidebar-header.svelte"; +import Input from "./sidebar-input.svelte"; +import Inset from "./sidebar-inset.svelte"; +import MenuAction from "./sidebar-menu-action.svelte"; +import MenuBadge from "./sidebar-menu-badge.svelte"; +import MenuButton from "./sidebar-menu-button.svelte"; +import MenuItem from "./sidebar-menu-item.svelte"; +import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; +import MenuSubButton from "./sidebar-menu-sub-button.svelte"; +import MenuSubItem from "./sidebar-menu-sub-item.svelte"; +import MenuSub from "./sidebar-menu-sub.svelte"; +import Menu from "./sidebar-menu.svelte"; +import Provider from "./sidebar-provider.svelte"; +import Rail from "./sidebar-rail.svelte"; +import Separator from "./sidebar-separator.svelte"; +import Trigger from "./sidebar-trigger.svelte"; +import Root from "./sidebar.svelte"; + +export { + Content, + Footer, + Group, + GroupAction, + GroupContent, + GroupLabel, + Header, + Input, + Inset, + Menu, + MenuAction, + MenuBadge, + MenuButton, + MenuItem, + MenuSkeleton, + MenuSub, + MenuSubButton, + MenuSubItem, + Provider, + Rail, + Root, + Separator, + // + Root as Sidebar, + Content as SidebarContent, + Footer as SidebarFooter, + Group as SidebarGroup, + GroupAction as SidebarGroupAction, + GroupContent as SidebarGroupContent, + GroupLabel as SidebarGroupLabel, + Header as SidebarHeader, + Input as SidebarInput, + Inset as SidebarInset, + Menu as SidebarMenu, + MenuAction as SidebarMenuAction, + MenuBadge as SidebarMenuBadge, + MenuButton as SidebarMenuButton, + MenuItem as SidebarMenuItem, + MenuSkeleton as SidebarMenuSkeleton, + MenuSub as SidebarMenuSub, + MenuSubButton as SidebarMenuSubButton, + MenuSubItem as SidebarMenuSubItem, + Provider as SidebarProvider, + Rail as SidebarRail, + Separator as SidebarSeparator, + Trigger as SidebarTrigger, + Trigger, + useSidebar, +}; \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-content.svelte b/src/lib/components/ui/sidebar/sidebar-content.svelte new file mode 100644 index 0000000..7ee167d --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-content.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-footer.svelte b/src/lib/components/ui/sidebar/sidebar-footer.svelte new file mode 100644 index 0000000..65979be --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/src/lib/components/ui/sidebar/sidebar-group-action.svelte new file mode 100644 index 0000000..ba0f622 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-group-action.svelte @@ -0,0 +1,31 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/src/lib/components/ui/sidebar/sidebar-group-content.svelte new file mode 100644 index 0000000..0065ea6 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-group-content.svelte @@ -0,0 +1,19 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/src/lib/components/ui/sidebar/sidebar-group-label.svelte new file mode 100644 index 0000000..5c1df86 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-group-label.svelte @@ -0,0 +1,29 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
    + {@render children?.()} +
    +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-group.svelte b/src/lib/components/ui/sidebar/sidebar-group.svelte new file mode 100644 index 0000000..d710a2e --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-group.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-header.svelte b/src/lib/components/ui/sidebar/sidebar-header.svelte new file mode 100644 index 0000000..65667d2 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-input.svelte b/src/lib/components/ui/sidebar/sidebar-input.svelte new file mode 100644 index 0000000..649db68 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-input.svelte @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-inset.svelte b/src/lib/components/ui/sidebar/sidebar-inset.svelte new file mode 100644 index 0000000..b77f97e --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -0,0 +1,22 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/src/lib/components/ui/sidebar/sidebar-menu-action.svelte new file mode 100644 index 0000000..7f702b3 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-action.svelte @@ -0,0 +1,37 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte new file mode 100644 index 0000000..bf797ef --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte @@ -0,0 +1,27 @@ + + +
    + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/src/lib/components/ui/sidebar/sidebar-menu-button.svelte new file mode 100644 index 0000000..6b23933 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-button.svelte @@ -0,0 +1,90 @@ + + + + +{#snippet Button({ props })} + {@const mergedProps = mergeProps(buttonProps, props)} + {#if child} + {@render child({ props: mergedProps })} + {:else} + + {/if} +{/snippet} + +{#if !tooltipContent} + {@render Button({})} +{:else} + + + {#snippet child({ props })} + {@render Button({ props })} + {/snippet} + + + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/src/lib/components/ui/sidebar/sidebar-menu-item.svelte new file mode 100644 index 0000000..9fdb872 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-item.svelte @@ -0,0 +1,19 @@ + + +
  • + {@render children?.()} +
  • \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte new file mode 100644 index 0000000..4589160 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte @@ -0,0 +1,32 @@ + + +
    + {#if showIcon} + + {/if} + + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte new file mode 100644 index 0000000..2ed7eba --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte @@ -0,0 +1,36 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + + {@render children?.()} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte new file mode 100644 index 0000000..b0ee510 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte @@ -0,0 +1,19 @@ + + +
  • + {@render children?.()} +
  • \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte new file mode 100644 index 0000000..6587745 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte @@ -0,0 +1,23 @@ + + +
      + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-menu.svelte b/src/lib/components/ui/sidebar/sidebar-menu.svelte new file mode 100644 index 0000000..519af7e --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-menu.svelte @@ -0,0 +1,19 @@ + + +
      + {@render children?.()} +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-provider.svelte b/src/lib/components/ui/sidebar/sidebar-provider.svelte new file mode 100644 index 0000000..51d5ba3 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -0,0 +1,49 @@ + + + + + +
    + {@render children?.()} +
    +
    \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-rail.svelte b/src/lib/components/ui/sidebar/sidebar-rail.svelte new file mode 100644 index 0000000..5f7d113 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-rail.svelte @@ -0,0 +1,35 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-separator.svelte b/src/lib/components/ui/sidebar/sidebar-separator.svelte new file mode 100644 index 0000000..146a2c5 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-separator.svelte @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/src/lib/components/ui/sidebar/sidebar-trigger.svelte new file mode 100644 index 0000000..e637b41 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar-trigger.svelte @@ -0,0 +1,32 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/sidebar/sidebar.svelte b/src/lib/components/ui/sidebar/sidebar.svelte new file mode 100644 index 0000000..3689d09 --- /dev/null +++ b/src/lib/components/ui/sidebar/sidebar.svelte @@ -0,0 +1,99 @@ + + +{#if collapsible === "none"} +
    + {@render children?.()} +
    +{:else if sidebar.isMobile} + sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} + {...restProps} + > + + + Sidebar + Displays the mobile sidebar. + +
    + {@render children?.()} +
    +
    +
    +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/components/ui/skeleton/index.js b/src/lib/components/ui/skeleton/index.js new file mode 100644 index 0000000..8252916 --- /dev/null +++ b/src/lib/components/ui/skeleton/index.js @@ -0,0 +1,7 @@ +import Root from "./skeleton.svelte"; + +export { + Root, + // + Root as Skeleton, +}; \ No newline at end of file diff --git a/src/lib/components/ui/skeleton/skeleton.svelte b/src/lib/components/ui/skeleton/skeleton.svelte new file mode 100644 index 0000000..1195a92 --- /dev/null +++ b/src/lib/components/ui/skeleton/skeleton.svelte @@ -0,0 +1,15 @@ + + +
    \ No newline at end of file diff --git a/src/lib/components/ui/spinner/index.js b/src/lib/components/ui/spinner/index.js new file mode 100644 index 0000000..19a61ff --- /dev/null +++ b/src/lib/components/ui/spinner/index.js @@ -0,0 +1 @@ +export { default as Spinner } from "./spinner.svelte"; \ No newline at end of file diff --git a/src/lib/components/ui/spinner/spinner.svelte b/src/lib/components/ui/spinner/spinner.svelte new file mode 100644 index 0000000..845035f --- /dev/null +++ b/src/lib/components/ui/spinner/spinner.svelte @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/table/index.js b/src/lib/components/ui/table/index.js new file mode 100644 index 0000000..1620d4a --- /dev/null +++ b/src/lib/components/ui/table/index.js @@ -0,0 +1,28 @@ +import Root from "./table.svelte"; +import Body from "./table-body.svelte"; +import Caption from "./table-caption.svelte"; +import Cell from "./table-cell.svelte"; +import Footer from "./table-footer.svelte"; +import Head from "./table-head.svelte"; +import Header from "./table-header.svelte"; +import Row from "./table-row.svelte"; + +export { + Root, + Body, + Caption, + Cell, + Footer, + Head, + Header, + Row, + // + Root as Table, + Body as TableBody, + Caption as TableCaption, + Cell as TableCell, + Footer as TableFooter, + Head as TableHead, + Header as TableHeader, + Row as TableRow, +}; \ No newline at end of file diff --git a/src/lib/components/ui/table/table-body.svelte b/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 0000000..9b0ff82 --- /dev/null +++ b/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,18 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-caption.svelte b/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 0000000..c3564b7 --- /dev/null +++ b/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,18 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-cell.svelte b/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 0000000..b734eed --- /dev/null +++ b/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-footer.svelte b/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 0000000..12a1dfe --- /dev/null +++ b/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,18 @@ + + +tr]:last:border-b-0", className)} + {...restProps} +> + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-head.svelte b/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 0000000..6b8533c --- /dev/null +++ b/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,21 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-header.svelte b/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 0000000..3081e65 --- /dev/null +++ b/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,18 @@ + + + + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table-row.svelte b/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 0000000..ccc3f41 --- /dev/null +++ b/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,21 @@ + + +svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", + className + )} + {...restProps} +> + {@render children?.()} + \ No newline at end of file diff --git a/src/lib/components/ui/table/table.svelte b/src/lib/components/ui/table/table.svelte new file mode 100644 index 0000000..55d72e4 --- /dev/null +++ b/src/lib/components/ui/table/table.svelte @@ -0,0 +1,21 @@ + + +
    + + {@render children?.()} +
    +
    \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/index.js b/src/lib/components/ui/tooltip/index.js new file mode 100644 index 0000000..b883804 --- /dev/null +++ b/src/lib/components/ui/tooltip/index.js @@ -0,0 +1,19 @@ +import Root from "./tooltip.svelte"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; +import Provider from "./tooltip-provider.svelte"; +import Portal from "./tooltip-portal.svelte"; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/tooltip-content.svelte b/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..ac9be9b --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,46 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/tooltip-portal.svelte b/src/lib/components/ui/tooltip/tooltip-portal.svelte new file mode 100644 index 0000000..bfb3f62 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-portal.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/tooltip-provider.svelte b/src/lib/components/ui/tooltip/tooltip-provider.svelte new file mode 100644 index 0000000..6d68c8a --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-provider.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..a2885f2 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/components/ui/tooltip/tooltip.svelte b/src/lib/components/ui/tooltip/tooltip.svelte new file mode 100644 index 0000000..dc88c32 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip.svelte @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/src/lib/config/api.js b/src/lib/config/api.js new file mode 100644 index 0000000..772f9ab --- /dev/null +++ b/src/lib/config/api.js @@ -0,0 +1,29 @@ +export const API = { + BASE_URL: 'https://clqms01-api.services-summit.my.id', // PROD + LOGIN: '/auth/login', + DASHBOARD: '/api/dashboard', + RESULT: '/api/result', + SAMPLE: '/api/sample', + PATIENTS: '/api/patient', + USERS: '/api/users', + CHECK: '/api/patient/check', + VALUESETDEF: '/api/valuesetdef', + VALUESET: '/api/valueset', + LOCATION: '/api/location', + CONTACT: '/api/contact', + OCCUPATION: '/api/occupation', + MEDICALSPECIALTY: '/api/specialty', + PATVISIT: '/api/patvisit', + VISITLIST: '/api/patvisit/patient/', + COUNTER: '/api/counter', + CONTAINER: '/api/specimen/containerdef', + PROVINCE: '/api/areageo/provinces', + CITY: '/api/areageo/cities', + ACCOUNT: '/api/organization/account', + SITE: '/api/organization/site', + DISCIPLINE: '/api/organization/discipline', + DEPARTMENT: '/api/organization/department', + WORKSTATION: '/api/organization/workstation', + TEST: '/api/tests', + TESTSITE: '/api/test/testdefsite', +}; diff --git a/src/lib/hooks/is-mobile.svelte.js b/src/lib/hooks/is-mobile.svelte.js new file mode 100644 index 0000000..293ae5f --- /dev/null +++ b/src/lib/hooks/is-mobile.svelte.js @@ -0,0 +1,9 @@ +import { MediaQuery } from "svelte/reactivity"; + +const DEFAULT_MOBILE_BREAKPOINT = 768; + +export class IsMobile extends MediaQuery { + constructor(breakpoint = DEFAULT_MOBILE_BREAKPOINT) { + super(`max-width: ${breakpoint - 1}px`); + } +} \ No newline at end of file diff --git a/src/lib/index.js b/src/lib/index.js new file mode 100644 index 0000000..856f2b6 --- /dev/null +++ b/src/lib/index.js @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/src/lib/utils.js b/src/lib/utils.js new file mode 100644 index 0000000..f79e2db --- /dev/null +++ b/src/lib/utils.js @@ -0,0 +1,8 @@ +import { clsx, } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs) { + return twMerge(clsx(inputs)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any \ No newline at end of file diff --git a/src/lib/utils/cleanEmptyStrings.js b/src/lib/utils/cleanEmptyStrings.js new file mode 100644 index 0000000..a60afb8 --- /dev/null +++ b/src/lib/utils/cleanEmptyStrings.js @@ -0,0 +1,11 @@ +export function cleanEmptyStrings(obj) { + if (Array.isArray(obj)) { + return obj.map(cleanEmptyStrings); + } else if (obj !== null && typeof obj === 'object') { + return Object.fromEntries( + Object.entries(obj).map(([key, value]) => [key, cleanEmptyStrings(value)]) + ); + } else { + return obj === '' ? null : obj; + } +} \ No newline at end of file diff --git a/src/lib/utils/formatUTCDate.js b/src/lib/utils/formatUTCDate.js new file mode 100644 index 0000000..f05d962 --- /dev/null +++ b/src/lib/utils/formatUTCDate.js @@ -0,0 +1,16 @@ +export function formatUTCDate(isoString) { + if (!isoString) return "-"; + try { + const date = new Date(isoString); + if (isNaN(date.getTime())) return "-"; + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + const hours = String(date.getHours()).padStart(2, "0"); + const minutes = String(date.getMinutes()).padStart(2, "0"); + const seconds = String(date.getSeconds()).padStart(2, "0"); + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } catch { + return isoString; + } +} \ No newline at end of file diff --git a/src/lib/utils/getUrl.js b/src/lib/utils/getUrl.js new file mode 100644 index 0000000..ae97614 --- /dev/null +++ b/src/lib/utils/getUrl.js @@ -0,0 +1,5 @@ +const baseUrl = "/api/preview/"; + +export function getUrl(address) { + return baseUrl + address.replace("uploads/", ""); +} \ No newline at end of file diff --git a/src/routes/+layout.server.js b/src/routes/+layout.server.js new file mode 100644 index 0000000..b569934 --- /dev/null +++ b/src/routes/+layout.server.js @@ -0,0 +1,17 @@ +export async function load({ url }) { + const routeConfig = { + '/patient': { + title: 'Patient List', + }, + '/': { + title: 'Dashboard', + } + }; + + const config = routeConfig[url.pathname] || { + title: '', + actions: [] + }; + + return config; +} \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..34acffe --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,55 @@ + + + + + + + + + +
    +
    + + + + + + + +
    +
    + +
    +
    + +
    + {@render children?.()} +
    +
    +
    + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..cc88df0 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,2 @@ +

    Welcome to SvelteKit

    +

    Visit svelte.dev/docs/kit to read the documentation

    diff --git a/src/routes/api/preview/[...path]/+server.js b/src/routes/api/preview/[...path]/+server.js new file mode 100644 index 0000000..93dc2e7 --- /dev/null +++ b/src/routes/api/preview/[...path]/+server.js @@ -0,0 +1,30 @@ +import { error } from '@sveltejs/kit'; +import { join } from 'path'; +import { createReadStream, existsSync } from 'fs'; +import mime from 'mime-types'; + + +export async function GET({ params }){ + const filePath = params.path; + + if (filePath.includes('..') || filePath.startsWith('/')) { + throw error(400, 'Invalid file path'); + } + + const fullPath = join(process.cwd(), 'uploads', filePath); + + if (!existsSync(fullPath)) { + throw error(404, 'File not found'); + } + + const fileStream = createReadStream(fullPath); + + const contentType = mime.lookup(fullPath) || 'application/octet-stream'; + + return new Response(fileStream, { + headers: { + 'Content-Type': contentType, + 'Cache-Control': 'public, max-age=3600', + } + }); +} \ No newline at end of file diff --git a/src/routes/api/upload/+server.js b/src/routes/api/upload/+server.js new file mode 100644 index 0000000..8811a27 --- /dev/null +++ b/src/routes/api/upload/+server.js @@ -0,0 +1,149 @@ +import { writeFile, mkdir, rename, unlink } from 'fs/promises'; +import crypto from 'crypto'; +import path from 'path'; +import process from "process"; + +export async function POST({ request }){ + const formData = await request.formData(); + const files = formData.getAll("files"); + + const allowedTypes = ["image/jpeg", "image/png", "application/pdf", "text/plain"]; + const maxSize = 2 * 1024 * 1024; + + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + + const uploadDir = path.join('uploads', 'temp', `${year}`, `${month}`); + const finalDir = path.join('uploads', `${year}`, `${month}`); + await mkdir(uploadDir, {recursive: true}); + + const savedFiles = []; + + for(const file of files) { + if (!allowedTypes.includes(file.type)) { + return new Response( + JSON.stringify({ message: `File type not allowed: ${file.type}` }), + { status: 400, headers: { "Content-Type": "application/json" } } + ); + } + + if (file.size > maxSize) { + return new Response( + JSON.stringify({ message: `File too large: ${file.name}` }), + { status: 400, headers: { "Content-Type": "application/json" } } + ); + } + + const randomName = crypto.randomUUID(); + const ext = path.extname(file.name); + const storedFileName = `${randomName}${ext}`; + const storedPath = path.join(uploadDir, storedFileName).replace(/\\/g, "/"); + const storedFinalPath = path.join(finalDir, storedFileName); + + const buffer = Buffer.from(await file.arrayBuffer()); + await writeFile(storedPath, buffer); + + savedFiles.push({ + original_name: file.name, + stored_path: storedPath, + mime_type: file.type, + size: file.size, + }); + } + + return new Response(JSON.stringify({ message: 'success', files: savedFiles }), { + status: 201, + headers: { 'Content-Type': 'application/json' } + }); +} + +export async function PUT({ request }){ + try { + const { attachments } = await request.json(); + + if (!attachments || !Array.isArray(attachments)) { + return new Response(JSON.stringify({ message: "Invalid request" }), { + status: 400, + headers: { "Content-Type": "application/json" } + }); + } + + const movedFiles = []; + const failedFiles = []; + const projectRoot = process.cwd(); + + for (const file of attachments) { + const oldPath = file.Address; + + const normalized = oldPath.replace(/\\/g, "/"); + const parts = normalized.split("/"); + + let year, month, fileName; + + if (parts[1] === "temp") { + year = parts[2]; + month = parts[3]; + fileName = parts[4]; + } else { + year = parts[1]; + month = parts[2]; + fileName = parts[3]; + } + + const newDir = path.join("uploads", year, month); + const newPath = path.join(newDir, fileName); + + const oldFullPath = path.join(projectRoot, oldPath); + const newFullPath = path.join(projectRoot, newPath); + + try { + await mkdir(path.dirname(newFullPath), { recursive: true }); + await rename(oldFullPath, newFullPath); + + movedFiles.push({ + old_path: oldPath.replace(/\\/g, "/"), + new_path: newPath.replace(/\\/g, "/"), + }); + } catch (err) { + console.error(`Failed to move ${oldPath}:`, err); + failedFiles.push({ old_path: oldPath, error: err.message }); + } + } + + return new Response( + JSON.stringify({ + message: "Processed", + moved: movedFiles, + failed: failedFiles, + attachments: movedFiles.map(f => ({ Address: f.new_path })) + }), + { status: 200, headers: { "Content-Type": "application/json" } } + ); + } catch (err) { + console.error(err); + return new Response(JSON.stringify({ message: "Server error", error: err.message }), { + status: 500, + headers: { "Content-Type": "application/json" } + }); + } +} + +export async function DELETE({ request }) { + try { + const { Address } = await request.json(); + + if (!Address.startsWith("uploads/") && !Address.startsWith("uploads/temp/")) { + return new Response(JSON.stringify({ success: false, message: "Invalid path" }), { status: 400 }); + } + + const filePath = path.join(process.cwd(), Address); + + await unlink(filePath); + + return new Response(JSON.stringify({ success: true }), { status: 200 }); + } catch (err) { + console.error("Delete error:", err); + return new Response(JSON.stringify({ success: false, message: err.message }), { status: 500 }); + } +} \ No newline at end of file diff --git a/src/routes/patient/+page.svelte b/src/routes/patient/+page.svelte new file mode 100644 index 0000000..27eff80 --- /dev/null +++ b/src/routes/patient/+page.svelte @@ -0,0 +1,34 @@ + + +
    + {#if masterDetail.showMaster} + + {/if} + + {#if masterDetail.showDetail} +
    + {#if masterDetail.mode === "view"} + + {:else if masterDetail.mode === "create"} + + {:else if masterDetail.mode === "edit"} + + {/if} +
    + {/if} +
    \ No newline at end of file diff --git a/src/routes/sidebar-07/+page.svelte b/src/routes/sidebar-07/+page.svelte new file mode 100644 index 0000000..8a194da --- /dev/null +++ b/src/routes/sidebar-07/+page.svelte @@ -0,0 +1,39 @@ + + + + + +
    +
    + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..10c4eeb --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,13 @@ +import adapter from '@sveltejs/adapter-auto'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://svelte.dev/docs/kit/adapters for more information about adapters. + adapter: adapter() + } +}; + +export default config; diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..0aed4a4 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,7 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; +import tailwindcss from '@tailwindcss/vite'; + +export default defineConfig({ + plugins: [tailwindcss(),sveltekit()] +});